home *** CD-ROM | disk | FTP | other *** search
- /*
- * dcc.c: Things dealing client to client connections.
- *
- * Written By Troy Rollo <troy@cbme.unsw.oz.au>
- *
- * Copyright(c) 1991
- *
- * See the COPYRIGHT file, or do a HELP IRCII COPYRIGHT
- * Heavily modified Colten Edwards 1996-97
- */
-
- /*
- * april 11, 1998
- * patched dcc overflow - nyt
- */
-
-
- #include "irc.h"
- #include <sys/stat.h>
- #include <stdarg.h>
- #include <stdio.h>
- #include <dirent.h>
-
-
- #include "ctcp.h"
- #include "crypt.h"
- #include "cdcc.h"
- #include "dcc.h"
- #include "hook.h"
- #include "ircaux.h"
- #include "lastlog.h"
- #include "newio.h"
- #include "output.h"
- #include "parse.h"
- #include "server.h"
- #include "status.h"
- #include "vars.h"
- #include "whois.h"
- #include "window.h"
- #include "screen.h"
- #include "ircterm.h"
- #include "hook.h"
- #include "misc.h"
- #include "tcl_bx.h"
- #include "userlist.h"
- #include "hash2.h"
-
- #include <float.h>
- #ifdef WINNT
- #include <windows.h>
- #endif
-
-
- static off_t filesize = 0;
-
- DCC_list * ClientList = NULL;
-
- static char DCC_current_transfer_buffer[BIG_BUFFER_SIZE/4];
- extern int dgets_errno;
-
-
- static void dcc_add_deadclient _((register DCC_list *));
- static void dcc_close _((char *, char *));
- static void dcc_getfile _((char *, char *));
- int dcc_open _((DCC_list *));
- static void dcc_really_erase _((void));
- static void dcc_rename _((char *, char *));
- static void dcc_send_raw _((char *, char *));
- static void output_reject_ctcp _((char *, char *));
- static void process_incoming_chat _((register DCC_list *));
- static void process_incoming_listen _((register DCC_list *));
- static void process_incoming_raw _((register DCC_list *));
- static void process_outgoing_file _((register DCC_list *, int));
- static void process_incoming_file _((register DCC_list *));
- static void DCC_close_filesend _((DCC_list *, char *));
- static void update_transfer_buffer _((char *format, ...));
-
- #ifdef NON_BLOCKING_CONNECTS
- static void dcc_got_connected _((DCC_list *));
- #endif
-
- static void dcc_update_stats _((DCC_list *));
- static void dcc_set_paths _((char *, char *));
- static void dcc_set_quiet _((char *, char *));
- static void dcc_tog_auto _((char *, char *));
- static void dcc_show_active _((char *, char *));
- static void dcc_help1 _((char *, char *));
-
- static unsigned char byteordertest _((void));
- static void dcc_reject_notify _((char *, char *, char *));
- static int get_to_from _((char *));
-
- static char *strip_path _((char *));
- static void dcc_tog_rename _((char *, char *));
- static char *check_paths _((char *));
- static void dcc_overwrite_toggle _((char *, char *));
-
- static void dcc_ftpget _((char *, char *));
- static void dcc_ftpsend _((char *, char *));
- static void dcc_nick _((char *, char *));
-
- static void process_outgoing_ftp _((DCC_list *));
- static void process_incoming_ftp _((register DCC_list *));
- #ifdef FTP_XMIT
- static void dcc_xmitget _((char *, char *, char *, char *));
- #endif
-
- #ifdef MIRC_BROKEN_DCC_RESUME
- void dcc_getfile_resume _((char *, char *));
- static void dcc_getfile_resume_demanded _((char *user, char *filename, char *port, char *offset));
- static void dcc_getfile_resume_start _((char *nick, char *filename, char *port, char *offset));
- #endif
-
-
-
- typedef void (*dcc_function) _((char *, char *));
- typedef struct
- {
- char * name;
- dcc_function function;
- char * help;
- } DCC_commands;
-
- DCC_commands *dcc_dllcommands = { NULL };
-
- DCC_commands dcc_commands[] =
- {
- { "ACTIVE", dcc_show_active, "\n- Displays active dcc and limit" },
- { "AUTO", dcc_tog_auto, "[on|off]\n- toggles auto-get on/off" },
- { "AUTO_RENAME",dcc_tog_rename, "[on|off]\n- toggles auto-rename on/off" },
- #ifndef PUBLIC_ACCESS
- { "BOT", dcc_chatbot, "[nick]\n- Starts a dcc bot connection with another bx client" },
- #endif
- { "CHAT", dcc_chat, "[nick]\n- Starts a dcc chat connection" },
- { "LIST", dcc_list, "\n- Lists dcc's in old format" },
- { "GLIST", dcc_glist, "\n- Lists dcc's in new format" },
-
- { "TSEND", dcc_filesend, "[nick|nick1,nick2,...] [filename] [[-e encrypt][-p port]]\n- TurboDCC sends filename to nick(s) using encrypt and port" },
- { "SEND", dcc_filesend, "[nick|nick1,nick2,...] [filename] [[-e encrypt][-p port]]\n- DCC sends filename to nick(s) using encrypt and port" },
- { "RESEND", dcc_resend, "[nick|nick1,nick2,...] [filename] [[-e encrypt][-p port]]\n- DCC resends filename to nick(s) using encrypt and port" },
- { "TRESEND", dcc_resend, "[nick|nick1,nick2,...] [filename] [[-e encrypt][-p port]]\n- TurboDCC resends filename to nick(s) using encrypt and port" },
-
- #ifndef PUBLIC_ACCESS
- { "GET", dcc_getfile, "[nick|nick1,nick2,...] [[filename][-e encrypt]]\n- DCC gets from nick(s) filename using encrypt if supplied" },
- { "TGET", dcc_getfile, "[nick|nick1,nick2,...] [[filename][-e encrypt]]\n- TurboDCC gets from nick(s) filename using encrypt if supplied" },
- { "REGET", dcc_regetfile, "[nick|nick1,nick2,...] [[filename][-e encrypt]]\n- DCC regets from nick(s) filename using encrypt if supplied" },
- { "TREGET", dcc_regetfile, "[nick|nick1,nick2,...] [[filename][-e encrypt]]\n- TurboDCC regets from nick(s) filename using encrypt if supplied" },
- #endif
- { "CLOSE", dcc_close, "[#all|#|[send|get|resend|reget|nick #|#all|-all|filename][type]]\n- Closes a dcc connection"},
- { "RENAME", dcc_rename, "[nick] [description] [new description]\n- Renames an incoming dcc file" },
-
-
- #ifdef MIRC_BROKEN_DCC_RESUME
- { "RESUME", dcc_getfile_resume, "[nick|nick1,nick2,...] [file] [-e password]\n- DCC resumes a file ala mirc. NOTE autoget must be off"},
- #endif
-
- #ifndef PUBLIC_ACCESS
- { "RAW", dcc_send_raw, "[nick] <text>\n- Sends text to a dcc raw connection to [nick]" },
- #endif
- { "QUIET", dcc_set_quiet, "[on|off]\n- toggle dcc quiet mode on/off" },
- { "STATS", dcc_stats, "\n- Displays dcc stats for this session" },
- { "PATHS", dcc_set_paths, "[on|off]\n- toggles display of paths on/off" },
- #ifndef PUBLIC_ACCESS
- { "OVERWRITE", dcc_overwrite_toggle, "[on|off]\n- toggle overwrite of files on/off" },
- #ifdef WANT_FTP
- { "FTP", dcc_ftpopen , "[hostname] [[user] [passwd] [-p port]]\n- Starts a ftp connection to hostname" },
-
- { "XRECV", dcc_ftpget, "experimental" },
- { "XSEND", dcc_ftpsend, "experimental" },
- #endif
- #endif
- { "EXEMPT", dcc_nick, "[+nick|+nick1,+nick2,...|nick|nick1,nick2,...]\n- Adds or removes nick(s) to the dcc exempt list which bypasses autoget" },
-
- { "HELP", dcc_help1, "help" },
- { NULL, (dcc_function) NULL, NULL }
- };
-
- #define BAR_LENGTH 50
- static int dcc_count = 1;
- int dcc_active_count = 0;
- static int doing_multi = 0;
- static int dcc_quiet = 0;
- static int dcc_paths = 0;
- static int dcc_overwrite_var = 0;
- double dcc_bytes_in = 0;
- double dcc_bytes_out = 0;
- double dcc_max_rate_in = 0.0;
- static double dcc_min_rate_in = DBL_MAX;
- double dcc_max_rate_out = 0.0;
- static double dcc_min_rate_out = DBL_MAX;
-
- unsigned int send_count_stat = 0;
- unsigned int get_count_stat = 0;
-
- char *last_chat_req = NULL;
-
- #define DCC_HASHSIZE 11
- HashEntry dcc_no_flood[DCC_HASHSIZE];
-
-
- char *dcc_types[] =
- {
- "<none>",
- "CHAT",
- "SEND",
- "GET",
- "RAW_LISTEN",
- "RAW",
- "RESEND",
- "REGET",
- "BOT",
- "FTP",
- "FTPGET",
- "FTPSEND",
- "XMITSEND",
- "XMITRECV",
- NULL
- };
-
- struct deadlist
- {
- DCC_list *it;
- struct deadlist *next;
- } *deadlist = NULL;
-
-
-
- static int dccBlockSize(void)
- {
- register int BlockSize, NewBlockSize;
- NewBlockSize = BlockSize = get_int_var(DCC_BLOCK_SIZE_VAR);
- if (BlockSize > 2048)
- BlockSize = 2048;
- else if (BlockSize < 16)
- BlockSize = 16;
- else if ((BlockSize % 2) != 0)
- {
- BlockSize = 8;
- while (BlockSize <= NewBlockSize)
- BlockSize *= 2;
- }
- if (NewBlockSize != BlockSize)
- set_int_var(DCC_BLOCK_SIZE_VAR, BlockSize);
- return (BlockSize);
- }
- /*
- * dcc_searchlist searches through the dcc_list and finds the client
- * with the the flag described in type set.
- */
- DCC_list *dcc_searchlist(char *name, char *user, unsigned type, unsigned flag, char *othername, char *userhost, int active)
- {
- register DCC_list **Client = NULL, *NewClient = NULL;
-
- int dcc_num = 0;
- if (user && *user == '#' && my_atol(user+1))
- {
- /* we got a number so find that instead */
- char *p;
- p = user;
- p++;
- dcc_num = my_atol(p);
- if (dcc_num > 0)
- {
- for(Client = (&ClientList); *Client; Client = (&(**Client).next))
- if (dcc_num && ((**Client).dccnum == dcc_num))
- return *Client;
- }
- }
- else
- {
- for (Client = (&ClientList); *Client ; Client = (&(**Client).next))
- {
- /*
- * The following things have to be true:
- * -> The types have to be the same
- * -> One of the following things is true:
- * -> `name' is NULL or `name' is the same as the
- * entry's description
- * *OR*
- * -> `othername' is the same as the entry's othername
- * -> `user' is the same as the entry's user-perr
- * -> One of the following is true:
- * -> `active' is 1 and the entry is active
- * -> `active' is 0 and the entry is not active
- * -> `active' is -1 (dont care)
- */
- if (
- ( ((**Client).flags & DCC_TYPES) == type ) &&
- ( (!name || ((**Client).description && !my_stricmp(name, (**Client).description))) ||
- (othername && (**Client).othername && !my_stricmp(othername, (**Client).othername)) ) &&
- ( user && !my_stricmp(user, (**Client).user) ) &&
- ( (active == -1) ||
- ((active == 0) && !((**Client).flags & DCC_ACTIVE)) ||
- ((active == 1) && ((**Client).flags & DCC_ACTIVE))
- )
- )
- return *Client;
- }
- }
- if (!flag)
- return NULL;
- *Client = NewClient = (DCC_list *) new_malloc(sizeof(DCC_list));
- NewClient->flags = type;
- NewClient->read = NewClient->write = NewClient->file = -1;
- NewClient->filesize = filesize;
- malloc_strcpy(&NewClient->description, name);
- malloc_strcpy(&NewClient->user, user);
- malloc_strcpy(&NewClient->othername, othername);
- malloc_strcpy(&NewClient->userhost, userhost);
- NewClient->packets_total = filesize ? (filesize / (dccBlockSize() + 1)) : 0;
- get_time(&NewClient->lasttime);
- if (dcc_count == 0) dcc_count = 1;
- NewClient->dccnum = dcc_count++;
- return NewClient;
- }
-
- /*
- * Added by Chaos: Is used in edit.c for checking redirect.
- */
- extern int dcc_active (char *user)
- {
- return (dcc_searchlist("chat", user, DCC_CHAT, 0, NULL, NULL, 1)) ? 1 : 0;
- }
-
- extern int dcc_activebot (char *user)
- {
- return (dcc_searchlist("chat", user, DCC_BOTMODE, 0, NULL, NULL, 1)) ? 1 : 0;
- }
-
- extern int dcc_activeraw (char *user)
- {
- return (dcc_searchlist(/*"RAW"*/NULL, user, DCC_RAW, 0, NULL, NULL, 1)) ? 1 : 0;
- }
-
-
- static void dcc_add_deadclient(register DCC_list *client)
- {
- struct deadlist *new;
-
- new = (struct deadlist *) new_malloc(sizeof(struct deadlist));
- new->next = deadlist;
- new->it = client;
- deadlist = new;
- }
-
- /*
- * dcc_erase searches for the given entry in the dcc_list and
- * removes it
- */
- int dcc_erase(DCC_list *Element)
- {
- register DCC_list **Client;
- int erase_one = 0;
- dcc_count = 1;
-
- for (Client = &ClientList; *Client; Client = &(**Client).next)
- {
- if (*Client == Element)
- {
- *Client = Element->next;
- if (Element->write != -1)
- FD_CLR(Element->write, &writables);
- Element->read = new_close(Element->read);
- Element->file = new_close(Element->file);
- new_free(&Element->othername);
- new_free(&Element->description);
- new_free(&Element->userhost);
- new_free(&Element->user);
- new_free(&Element->buffer);
- new_free(&Element->encrypt);
- new_free(&Element->cksum);
- new_free(&Element->dccbuffer);
- if (Element->dcc_handler)
- (Element->dcc_handler)(NULL, NULL);
- new_free((char **)&Element);
- erase_one++;
- break;
- }
- }
- for (Client = &ClientList; *Client; Client = &(**Client).next)
- (*Client)->dccnum = dcc_count++;
- if (erase_one)
- {
- *DCC_current_transfer_buffer = 0;
- }
- return erase_one;
- }
-
- static void dcc_really_erase _((void))
- {
- struct deadlist *dies = NULL;
- for (;(dies = deadlist) != NULL;)
- {
- deadlist = deadlist->next;
- dcc_erase(dies->it);
- new_free(&dies);
- }
- }
-
- /*
- * Set the descriptor set to show all fds in Client connections to
- * be checked for data.
- */
- extern void set_dcc_bits (fd_set *rd, fd_set *wd)
- {
- register DCC_list *Client;
- unsigned int flag;
- unsigned int fast_dcc = get_int_var(DCC_FAST_VAR);
-
- for (Client = ClientList; Client != NULL; Client = Client->next)
- {
-
- flag = Client->flags & DCC_TYPES;
- if (Client->write > -1)
- {
- #ifdef NON_BLOCKING_CONNECTS
- #ifdef DCC_CNCT_PEND
- if (Client->flags & DCC_CNCT_PEND)
- FD_SET(Client->write, wd);
- else
- #endif
- if (((flag == DCC_FILEOFFER) ||
- (flag == DCC_RESENDOFFER) ||
- (flag == DCC_FTPSEND)) &&
- !Client->eof && fast_dcc)
- FD_SET(Client->write, wd);
- #endif
- }
- if (Client->read > -1)
- FD_SET(Client->read, rd);
- }
- if (!ClientList && dcc_active_count)
- dcc_active_count = 0; /* A HACK */
- }
-
- #ifdef NON_BLOCKING_CONNECTS
- static void dcc_got_connected(DCC_list *client)
- {
- struct sockaddr_in remaddr = {0};
- int rl = sizeof(remaddr);
-
- if (getpeername(client->read, (struct sockaddr *) &remaddr, &rl) != -1)
- {
-
- FD_CLR(client->read, &writables);
- if (client->flags & DCC_OFFER)
- {
- client->flags &= ~DCC_OFFER;
-
- if ((client->flags & DCC_TYPES) != DCC_RAW)
- {
-
- if (do_hook(DCC_CONNECT_LIST, "%s %s %s %d", client->user,
- dcc_types[client->flags&DCC_TYPES],inet_ntoa(remaddr.sin_addr),
- ntohs(remaddr.sin_port)))
- {
- if (!dcc_quiet)
- put_it("%s", convert_output_format(fget_string_var(FORMAT_DCC_CONNECT_FSET),
- "%s %s %s %s %s %d", update_clock(GET_TIME),
- dcc_types[client->flags&DCC_TYPES], client->user,
- client->userhost?client->userhost:"u@h", inet_ntoa(remaddr.sin_addr), (int) ntohs(remaddr.sin_port)));
- }
-
- }
- }
- get_time(&client->starttime);
- client->flags &= ~DCC_CNCT_PEND;
- if (((client->flags & DCC_TYPES) == DCC_REGETFILE))
- {
- /* send a packet to the sender with transfer resume instructions */
- put_it("%s", convert_output_format("$G %RDCC %YTelling uplink we want to start at%n: $0", "%l", client->transfer_orders.byteoffset));
- send(client->read, (const char *)&client->transfer_orders, sizeof(struct transfer_struct), 0);
- }
- else if (((client->flags & DCC_TYPES) == DCC_FTPOPEN))
- {
- if ((dcc_printf(client->read, "user %s\n", client->othername) < 0) || (dcc_printf(client->read, "pass %s\n", client->encrypt) < 0))
- {
- client->flags |= DCC_DELETE;
- put_it(convert_output_format("%gFTP%n command failed write", NULL, NULL));
- new_free(&client->encrypt);
- return;
- }
- client->flags &= ~DCC_WAIT;
- client->flags |= DCC_ACTIVE;
- dcc_printf(client->read, "type i\n");
- new_free(&client->encrypt);
- return;
- }
- if (!get_int_var(DCC_FAST_VAR) && !(client->flags & DCC_TDCC))
- {
- set_blocking(client->read);
- if (client->read != client->write)
- set_blocking(client->write);
- }
- }
-
- }
- #endif
-
- /*
- * Check all DCCs for data, and if they have any, perform whatever
- * actions are required.
- */
- extern void dcc_check (fd_set *Readables, fd_set *Writables)
- {
- register DCC_list **Client;
- int previous_server;
- int lastlog_level;
- register int flags;
- #ifdef NON_BLOCKING_CONNECTS
- int fast_dcc = get_int_var(DCC_FAST_VAR);
- #endif
-
-
- for (Client = (&ClientList); *Client != NULL;)
- {
- flags = (*Client)->flags;
- #ifdef NON_BLOCKING_CONNECTS
- #ifdef DCC_CNCT_PEND
- if (flags & DCC_CNCT_PEND)
- dcc_got_connected(*Client);
- #endif
- if (fast_dcc && ((flags & DCC_TYPES) != DCC_RAW_LISTEN) && (*Client)->write != -1 && FD_ISSET((*Client)->write, Writables))
- {
- FD_CLR((*Client)->write, Writables);
- switch(flags & DCC_TYPES)
- {
-
- #ifdef WANT_FTP
- case DCC_FTPSEND:
- process_outgoing_ftp(*Client);
- break;
- #endif
- case DCC_RESENDOFFER:
- case DCC_FILEOFFER:
- process_outgoing_file(*Client, 0);
- }
- }
- #endif
- if (!(flags & DCC_DELETE) && (*Client)->read != -1)
- {
- previous_server = from_server;
- from_server = -1;
- message_from(NULL, LOG_DCC);
- lastlog_level = set_lastlog_msg_level(LOG_DCC);
-
- if (FD_ISSET((*Client)->read, Readables))
- {
- FD_CLR((*Client)->read, Readables);
- switch(flags&DCC_TYPES)
- {
- case DCC_BOTMODE:
- case DCC_CHAT:
- from_server = previous_server;
- process_incoming_chat(*Client);
- from_server = -1;
- break;
- case DCC_RAW_LISTEN:
- process_incoming_listen(*Client);
- break;
- case DCC_RAW:
- process_incoming_raw(*Client);
- break;
- case DCC_FILEOFFER:
- case DCC_RESENDOFFER:
- process_outgoing_file(*Client, 1);
- break;
- case DCC_FILEREAD:
- case DCC_REGETFILE:
- process_incoming_file(*Client);
- break;
- #ifdef WANT_FTP
- case DCC_FTPOPEN:
- case DCC_FTPGET:
- process_incoming_ftp(*Client);
- break;
- case DCC_FTPSEND:
- process_outgoing_ftp(*Client);
- break;
- case DCC_XMITSEND:
- case DCC_XMITRECV:
- break;
- #endif
- }
- }
- message_from(NULL, LOG_CRAP);
- (void) set_lastlog_msg_level(lastlog_level);
- from_server = previous_server;
- }
- if (flags & DCC_DELETE)
- dcc_add_deadclient(*Client);
- Client = (&(**Client).next);
- }
- dcc_really_erase();
- }
-
- /*
- * Process a DCC command from the user.
- */
- extern void process_dcc(char *args)
- {
- char *command;
- int i;
- int lastlog_level;
-
- if (!(command = next_arg(args, &args)))
- return;
- for (i = 0; dcc_commands[i].name != NULL; i++)
- {
- if (!my_stricmp(dcc_commands[i].name, command))
- {
- message_from(NULL, LOG_DCC);
- lastlog_level = set_lastlog_msg_level(LOG_DCC);
- dcc_commands[i].function(dcc_commands[i].name, args);
- message_from(NULL, LOG_CRAP);
- (void) set_lastlog_msg_level(lastlog_level);
- return;
- }
- }
- put_it("%s", convert_output_format("$G Unknown %RDCC%n command: $0", "%s", command));
- }
-
- int dcc_open _((DCC_list *Client))
- {
- char *user,
- *Type;
- struct in_addr myip;
- struct sockaddr_in remaddr;
- int rl = sizeof(remaddr);
- int old_server;
-
- user = Client->user;
- old_server = from_server;
-
- if (from_server == -1)
- from_server = get_window_server(0);
-
- myip.s_addr = server_list[from_server].local_addr.s_addr;
-
- #if 0
- if (myip.s_addr == htonl(0x00000000) || myip.s_addr == htonl(0x7f000001))
- myip.s_addr = MyHostAddr.s_addr;
- #endif
- Type = dcc_types[Client->flags & DCC_TYPES];
- if (Client->flags & DCC_TDCC)
- {
- switch(Client->flags & DCC_TYPES)
- {
- case DCC_FILEOFFER:
- Type = "TSEND";
- break;
- case DCC_FILEREAD:
- Type = "TGET";
- break;
- case DCC_RESENDOFFER:
- Type = "TRESEND";
- break;
- case DCC_REGETFILE:
- Type = "TREGET";
- break;
- }
- }
-
-
- if (Client->flags & DCC_OFFER)
- {
- message_from(NULL, LOG_DCC);
- #ifdef DCC_CNCT_PEND
- Client->flags |= DCC_CNCT_PEND;
- #endif
- /*BLAH!*/
- Client->remport = ntohs(Client->remport);
- #ifdef WINNT
- if ((Client->write = connect_by_number(inet_ntoa(Client->remote), &Client->remport, SERVICE_CLIENT, PROTOCOL_TCP, 0)) < 0)
- #else
- if ((Client->write = connect_by_number(inet_ntoa(Client->remote), &Client->remport, SERVICE_CLIENT, PROTOCOL_TCP, 1)) < 0)
- #endif
- {
- put_it("%s", convert_output_format("$G %RDCC%n Unable to create connection: $0-", "%s", errno ? strerror(errno) : "Unknown Host"));
- message_from(NULL, LOG_CRAP);
- dcc_erase(Client);
- from_server = old_server;
- return 0;
- }
- /* BLAH! */
- Client->remport = htons(Client->remport);
- Client->read = Client->write;
- new_open(Client->read);
- Client->flags |= DCC_ACTIVE;
- if ((getpeername(Client->read, (struct sockaddr *) &remaddr, &rl)) != -1)
- {
-
- Client->flags &= ~DCC_OFFER;
- if (get_to_from(Type) != -1)
- dcc_active_count++;
- if ((Client->flags & DCC_TYPES) != DCC_RAW)
- {
- if (do_hook(DCC_CONNECT_LIST,"%s %s %s %d",
- user, Type, inet_ntoa(remaddr.sin_addr),
- ntohs(remaddr.sin_port)))
- if (!dcc_quiet)
- put_it("%s", convert_output_format(fget_string_var(FORMAT_DCC_CONNECT_FSET),
- "%s %s %s %s %s %d", update_clock(GET_TIME), Type, user, Client->userhost?Client->userhost:"u@h",
- inet_ntoa(remaddr.sin_addr), (int)ntohs(remaddr.sin_port)));
- }
- }
- message_from(NULL, LOG_CRAP);
- get_time(&Client->starttime);
- Client->bytes_read = Client->bytes_sent = 0L;
- from_server = old_server;
- return 1;
- }
- else
- {
- unsigned short portnum = Client->local_port;
-
- #ifdef DCC_CNCT_PEND
- Client->flags |= DCC_WAIT|DCC_CNCT_PEND;
- #else
- Client->flags |= DCC_WAIT;
- #endif
- if (Client->remport)
- portnum = Client->remport;
-
- message_from(NULL, LOG_DCC);
- #ifdef WINNT
- if ((Client->read = connect_by_number(NULL, &portnum, SERVICE_SERVER, PROTOCOL_TCP, 0)) < 0)
- #else
- if ((Client->read = connect_by_number(NULL, &portnum, SERVICE_SERVER, PROTOCOL_TCP, 1)) < 0)
- #endif
- {
- put_it("%s", convert_output_format("$G %RDCC%n Unable to create connection: $0-", "%s", errno ? strerror(errno) : "Unknown Host"));
- message_from(NULL, LOG_CRAP);
- dcc_erase(Client);
- from_server = old_server;
- return 0;
- }
- if (get_to_from(Type) != -1)
- dcc_active_count++;
- if (Client->flags & DCC_TWOCLIENTS)
- {
- /* patch to NOT send pathname accross */
- char *nopath;
-
- #if defined(WINNT) || defined(__EMX__)
- if ( ((Client->flags & DCC_FILEOFFER)== DCC_FILEOFFER) && ((nopath = strrchr(Client->description, '\\')) || (nopath = strrchr(Client->description, '/')) ))
- #else
- if (((Client->flags & DCC_FILEOFFER)== DCC_FILEOFFER) && (nopath = strrchr(Client->description, '/')))
- #endif
- nopath++;
- else
- nopath = Client->description;
-
- if (Client->filesize)
- send_ctcp(CTCP_PRIVMSG, user, CTCP_DCC,
- "%s %s %lu %u %lu", Type, nopath,
- (u_long) ntohl(myip.s_addr),
- (u_short) portnum,
- (unsigned long)Client->filesize);
- else if ((Client->flags & DCC_TYPES) == DCC_BOTMODE)
- send_ctcp(CTCP_NOTICE, user, CTCP_BOTLINK,
- "%s %s %lu %u %s", Type, nopath,
- (u_long) ntohl(myip.s_addr),
- (u_short) portnum, Client->encrypt?Client->encrypt:"");
- else
- send_ctcp(CTCP_PRIVMSG, user, CTCP_DCC,
- "%s %s %lu %u", Type, nopath,
- (u_long) ntohl(myip.s_addr),
- (u_short) portnum);
- message_from(NULL, LOG_DCC);
- if (!doing_multi && !dcc_quiet)
- put_it("%s", convert_output_format(fget_string_var(FORMAT_SEND_DCC_CHAT_FSET),
- "%s %s %s", update_clock(GET_TIME), Type, user));
- message_from(NULL, LOG_CRAP);
- }
- #ifdef MIRC_BROKEN_DCC_RESUME
- malloc_strcpy(&Client->othername, ltoa(portnum));
- #endif
- new_open(Client->read);
- Client->starttime.tv_sec = Client->starttime.tv_usec = 0;
- Client->local_port = portnum;
- from_server = old_server;
- return 2;
- }
- message_from(NULL, LOG_CRAP);
- }
- void add_userhost_to_dcc(WhoisStuff *stuff, char *nick, char *args)
- {
- DCC_list *Client;
- Client = dcc_searchlist("chat", nick, DCC_CHAT, 0, NULL, NULL, -1);
- if (!stuff || !nick || !stuff->nick || !stuff->user || !stuff->host || !strcmp(stuff->user, "<UNKNOWN>"))
- return;
- if (Client)
- Client->userhost = m_sprintf("%s@%s", stuff->user, stuff->host);
- return;
- }
-
- void dcc_chat (char *command, char *args)
- {
- char *user;
- char *nick;
-
- char *passwd = NULL;
- char *port = NULL;
- char *equal_user = NULL;
- DCC_list *Client;
-
- if ((user = next_arg(args, &args)) == NULL)
- {
- put_it("%s", convert_output_format("$G %RDCC%n You must supply a nickname for DCC chat", NULL, NULL));
- return;
- }
- while (args && *args)
- {
- char *argument = next_arg(args, &args);
- if (argument && strlen(argument) >= 2)
- {
- if (argument[0] == '-' || argument[1] == 'e')
- passwd = next_arg(args, &args);
- else if (argument[0] == '-' || argument[1] == 'p')
- port = next_arg(args, &args);
- }
- }
-
- while ((nick = next_in_comma_list(user, &user)))
- {
- if (!nick || !*nick)
- break;
-
- Client = dcc_searchlist("chat", nick, DCC_CHAT, 1, NULL, NULL, -1);
-
- if ((Client->flags & DCC_ACTIVE) || (Client->flags & DCC_WAIT))
- {
- put_it("%s", convert_output_format("$G %RDCC%n A previous DCC chat to $0 exists", "%s", nick));
- return;
- }
- if (port)
- Client->remport = atol(port);
- Client->flags |= DCC_TWOCLIENTS;
- if (passwd)
- Client->encrypt = m_strdup(passwd);
- equal_user = alloca(strlen(nick)+4);
- strcpy(equal_user, "="); strcat(equal_user, nick);
- addtabkey(equal_user, "msg", 0);
-
- dcc_open(Client);
- add_to_userhost_queue(nick, add_userhost_to_dcc, "%d %s", Client->read, nick);
- }
- }
-
-
- void dcc_chatbot (char *command, char *args)
- {
- char *user;
- char *passwd = NULL;
- DCC_list *Client;
- char *port = NULL;
-
- if ((user = next_arg(args, &args)) == NULL)
- {
- put_it("%s", convert_output_format("$G %RDCC%n You must supply a nickname for DCC bot", NULL, NULL));
- return;
- }
- while (args && *args)
- {
- char *argument = next_arg(args, &args);
- if (argument && argument[0] == '-' && strlen(argument) >=2)
- {
- if ((*(argument+1)) == 'e')
- passwd = next_arg(args, &args);
- else if ((*(argument+1)) == 'p')
- port = next_arg(args, &args);
- }
- }
-
- Client = dcc_searchlist("chat", user, DCC_BOTMODE, 1, NULL, NULL, -1);
-
- if ((Client->flags & DCC_ACTIVE) || (Client->flags & DCC_WAIT))
- {
- put_it("%s", convert_output_format("$G %RDCC%n A previous DCC Bot to $0 exists", "%s", user));
- return;
- }
- Client->flags |= DCC_TWOCLIENTS;
- if (passwd)
- Client->encrypt = m_strdup(passwd);
- if (port)
- Client->remport = atol(port);
- dcc_open(Client);
- add_to_userhost_queue(user, add_userhost_to_dcc, "%d %s", Client->read, user);
- }
-
- extern char *dcc_raw_listen (int port)
- {
- DCC_list *Client;
- char *PortName;
- struct sockaddr_in locaddr;
- char *RetName = NULL;
- int size;
- int lastlog_level;
-
- lastlog_level = set_lastlog_msg_level(LOG_DCC);
- if (port && port < 1025)
- {
- put_it("%s", convert_output_format("$G %RDCC%n Cannot bind to a privileged port", NULL, NULL));
- (void) set_lastlog_msg_level(lastlog_level);
- return NULL;
- }
- PortName = ltoa(port);
- Client = dcc_searchlist("raw_listen", PortName, DCC_RAW_LISTEN, 1, NULL, NULL, -1);
- if (Client->flags & DCC_ACTIVE)
- {
- put_it("%s", convert_output_format("$G %RDCC%n A previous Raw Listen on $0 exists", "%s", PortName));
- set_lastlog_msg_level(lastlog_level);
- return RetName;
- }
- memset((char *) &locaddr, 0, sizeof(locaddr));
- locaddr.sin_family = AF_INET;
- locaddr.sin_addr.s_addr = htonl(INADDR_ANY);
- locaddr.sin_port = htons(port);
- if (0 > (Client->read = socket(AF_INET, SOCK_STREAM, 0)))
- {
- dcc_erase(Client);
- put_it("%s", convert_output_format("$G %RDCC%n socket() failed: $0-", "%s", strerror(errno)));
- (void) set_lastlog_msg_level(lastlog_level);
- return RetName;
- }
-
- new_open(Client->read);
- set_socket_options(Client->read);
- if (bind(Client->read, (struct sockaddr *) &locaddr, sizeof(locaddr)) == -1)
- {
- dcc_erase(Client);
- put_it("%s", convert_output_format("$G %RDCC%n Could not bind port: $0-", "%s", strerror(errno)));
- (void) set_lastlog_msg_level(lastlog_level);
- return RetName;
- }
- listen(Client->read, 4);
- size = sizeof(locaddr);
- get_time(&Client->starttime);
- getsockname(Client->read, (struct sockaddr *) &locaddr, &size);
- Client->write = ntohs(locaddr.sin_port);
- Client->flags |= DCC_ACTIVE;
- malloc_strcpy(&Client->user, ltoa(Client->write));
- malloc_strcpy(&RetName, Client->user);
- (void) set_lastlog_msg_level(lastlog_level);
- return RetName;
- }
-
- extern char *dcc_raw_connect(char *host, u_short port)
- {
- DCC_list *Client;
- char *PortName;
- struct in_addr address;
- struct hostent *hp;
- int lastlog_level;
-
- lastlog_level = set_lastlog_msg_level(LOG_DCC);
- if ((address.s_addr = inet_addr(host)) == -1)
- {
- hp = gethostbyname(host);
- if (!hp)
- {
- put_it("%s", convert_output_format("$G %RDCC%n Unknown host: $0-", "%s", host));
- set_lastlog_msg_level(lastlog_level);
- return m_strdup(empty_string);
- }
- memcpy(&address, hp->h_addr, sizeof(address));
- }
- Client = dcc_searchlist(host, ltoa(port), DCC_RAW, 1, NULL, NULL, -1);
- if (Client->flags & DCC_ACTIVE)
- {
- put_it("%s", convert_output_format("$G %RDCC%n A previous DCC raw to $0 on $1 exists", "%s %d", host, port));
- set_lastlog_msg_level(lastlog_level);
- return m_strdup(empty_string);
- }
- /* Sorry. The missing 'htons' call here broke $connect() */
- Client->remport = htons(port);
- memcpy((char *) &Client->remote, (char *) &address, sizeof(address));
- Client->flags = DCC_OFFER | DCC_RAW;
- if (!dcc_open(Client))
- return m_strdup(empty_string);
- PortName = ltoa(Client->read);
- Client->user = m_strdup(PortName);
- if (do_hook(DCC_RAW_LIST, "%s %s E %d", PortName, host, port))
- if (do_hook(DCC_CONNECT_LIST,"%s RAW %s %d",PortName, host, port))
- put_it("%s", convert_output_format(fget_string_var(FORMAT_DCC_CONNECT_FSET),
- "%s %s %s %s %s %d", update_clock(GET_TIME), "RAW", host,
- Client->userhost?Client->userhost:"u@h", PortName, port));
- (void) set_lastlog_msg_level(lastlog_level);
- return m_strdup(ltoa(Client->read));
- }
-
- void real_dcc_filesend(char *filename, char *real_file, char *user, char *passwd, int type, int portnum)
- {
- DCC_list *Client;
- struct stat stat_buf;
- char *nick = NULL;
-
- stat_file(filename, &stat_buf);
- #ifdef S_IFDIR
- if (stat_buf.st_mode & S_IFDIR)
- {
- put_it("%s", convert_output_format("$G %RDCC%n Cannot send a directory", NULL, NULL));
- return;
- }
- #endif
- #if !defined(WINNT) && !defined(__EMX__)
- if (!strncmp(filename, "/etc/", 5))
- {
- put_it("%s", convert_output_format("$G %RDCC%n Send request for /etc rejected", NULL, NULL));
- return;
- }
- #endif
- filesize = stat_buf.st_size;
- while ((nick = next_in_comma_list(user, &user)))
- {
- if (!nick || !*nick)
- break;
- Client = dcc_searchlist(filename, nick, type, 1, real_file, NULL, -1);
- filesize = 0;
- if (!(Client->flags & DCC_ACTIVE) && !(Client->flags & DCC_WAIT))
- {
- Client->flags |= DCC_TWOCLIENTS;
- Client->remport = portnum;
- dcc_open(Client);
- } else
- put_it("%s", convert_output_format("$G %RDCC%n A previous DCC send:$0 to $1 exists", "%s %s", filename, nick));
- }
- }
-
- void dcc_resend(char *command, char *args)
- {
- char *user = NULL;
- char *filename = NULL,
- *fullname = NULL;
- char *passwd = NULL;
- char *FileBuf = NULL;
- int portnum = 0;
- int tdcc = 0;
-
- if (!(user = next_arg(args, &args)) || !(filename = next_arg(args, &args)))
- {
- put_it("%s", convert_output_format("$G %RDCC%n You must supply a nickname and a filename for DCC resend", NULL, NULL));
- return;
- }
- #if defined(WINNT) || defined(__EMX__)
- if (*filename == '\\' || *filename == '/')
- #else
- if (*filename == '/')
- #endif
- {
- malloc_strcpy(&FileBuf, filename);
- }
- else if (*filename == '~')
- {
- if (!(fullname = expand_twiddle(filename)))
- {
- put_it("%s", convert_output_format("$G %RDCC%n Unable to expand: $0", "%s", filename));
- return;
- }
- malloc_strcpy(&FileBuf, fullname);
- new_free(&fullname);
- }
- else
- {
- char current_dir[BIG_BUFFER_SIZE+1];
- *current_dir = 0;
- getcwd(current_dir, BIG_BUFFER_SIZE - strlen(filename) - 4);
- malloc_sprintf(&FileBuf, "%s/%s", current_dir, filename);
- }
-
- if (access(FileBuf, R_OK))
- {
- put_it("%s", convert_output_format("$G %RDCC%n Cannot access: $0", "%s", FileBuf));
- new_free(&FileBuf);
- return;
- }
- if (command)
- tdcc = !my_stricmp(command, "TRESEND");
-
- while (args && *args)
- {
- char *argument = next_arg(args, &args);
- if (argument && strlen(argument) >=2)
- {
- if (*argument == '-' || *(argument+1) == 'e')
- passwd = next_arg(args, &args);
- else if (*argument == '-' || *(argument+1) == 'p')
- {
- char *v = next_arg(args, &args);
- portnum = (v) ? my_atol(v) : 0;
- }
- }
- }
-
- real_dcc_filesend(FileBuf,filename, user, passwd, tdcc?DCC_TDCC|DCC_RESENDOFFER:DCC_RESENDOFFER, portnum);
- new_free(&FileBuf);
- }
-
- void dcc_filesend (char *command, char *args)
- {
- char *user = NULL;
- char *filename = NULL,
- *fullname = NULL;
- char FileBuf[BIG_BUFFER_SIZE + 1];
- char *passwd = NULL;
- int portnum = 0;
- int tdcc = 0;
-
- *FileBuf = 0;
- if (!(user = next_arg(args, &args)) || !(filename = next_arg(args, &args)))
- {
- put_it("%s", convert_output_format("$G %RDCC%n You must supply a nickname and a filename for DCC send", NULL, NULL));
- return;
- }
- if (command)
- tdcc = !my_stricmp(command, "TSEND");
-
- #if defined(WINNT) || defined(__EMX__)
- if (*filename == '\\' || *filename == '/')
- #else
- if (*filename == '/')
- #endif
- strcpy(FileBuf, filename);
-
- else if (*filename == '~')
- {
- if (0 == (fullname = expand_twiddle(filename)))
- {
- put_it("%s", convert_output_format("$G %RDCC%n Unable to expand: $0", "%s", filename));
- return;
- }
- strcpy(FileBuf, fullname);
- new_free(&fullname);
- }
- else
- {
- getcwd(FileBuf, BIG_BUFFER_SIZE);
- strcat(FileBuf, "/");
- strcat(FileBuf, filename);
- }
-
- while (args && *args)
- {
- char *argument = next_arg(args, &args);
- if (argument && strlen(argument) >= 2)
- {
- if (*argument == '-' && *(argument+1) == 'e')
- passwd = next_arg(args, &args);
- else if (*argument == '-' && *(argument+1) == 'p')
- {
- char *v = next_arg(args, &args);
- portnum = (v) ? my_atol(v) : 0;
- }
- }
- }
-
- #if defined(WINNT) || defined(__EMX__)
- convert_unix(FileBuf);
- #endif
- if (!strchr(FileBuf, '*') && access(FileBuf, R_OK))
- {
- put_it("%s", convert_output_format("$G %RDCC%n Cannot access: $0", "%s", FileBuf));
- return;
- }
- else
- if (strchr(FileBuf, '*'))
- {
- char *path = NULL;
- char *thefile;
- DIR *dp;
- struct dirent *dir;
- struct stat stbuf;
- char *filebuf = NULL;
- char *expand = NULL;
- int count = 0;
- malloc_strcpy(&path, FileBuf);
-
- if ((thefile = strrchr(path, '/')) != NULL)
- *thefile++ = '\0';
- else {
- malloc_strcpy(&path, "~");
- thefile = FileBuf;
- }
- expand = expand_twiddle(path);
-
- if ((dp = opendir(expand)) == NULL)
- {
- put_it("%s", convert_output_format("$G %RDCC%n Cannot access directory: $0", "%s", expand));
- new_free(&expand);
- new_free(&path);
- return;
- }
-
- while(1)
- {
- dir = readdir(dp);
- if (!dir)
- break;
- if (dir->d_ino == 0)
- continue;
- if (!match(thefile, dir->d_name))
- continue;
- malloc_sprintf(&filebuf, "%s/%s", expand, dir->d_name);
- stat(filebuf, &stbuf);
- if (S_ISDIR(stbuf.st_mode))
- continue;
- count++;
- real_dcc_filesend(filebuf, dir->d_name, user, passwd, tdcc?DCC_TDCC|DCC_FILEOFFER:DCC_FILEOFFER, 0);
- }
- new_free(&filebuf);
- if (!dcc_quiet)
- {
- if (count)
- put_it("%s", convert_output_format("$G %RDCC%n Sent DCC SEND request to $0 for files $1", "%s %s", user, FileBuf));
- else
- put_it("%s", convert_output_format("$G %RDCC%n No Files found matching $0", "%s", FileBuf));
- }
- new_free(&path);
- new_free(&expand);
- return;
- }
- real_dcc_filesend(FileBuf, filename, user, passwd, tdcc?DCC_TDCC|DCC_FILEOFFER:DCC_FILEOFFER, portnum);
- }
-
- void multiget(char *usern, char *filen)
- {
- DCC_list *dccList;
- char *newbuf = NULL;
- char *expand = NULL;
- char *q = NULL;
- doing_multi = 1;
- if ((q = strchr(filen, ' ')))
- *q = 0;
- for (dccList = ClientList; dccList ; dccList = dccList->next)
- {
- if((match(dccList->description, filen) || match(filen, dccList->description))&&
- !my_stricmp(usern, dccList->user) &&
- (dccList->flags & DCC_TYPES) == DCC_FILEREAD)
- {
- if (get_string_var(DCC_DLDIR_VAR))
- {
- expand = expand_twiddle(get_string_var(DCC_DLDIR_VAR));
- malloc_sprintf(&newbuf, "%s %s/%s", usern, expand, dccList->description);
- } else
- malloc_sprintf(&newbuf, "%s %s", usern, dccList->description);
- if (!dcc_quiet)
- put_it("%s", convert_output_format("$G %RDCC%n Attempting DCC get: $0", "%s", dccList->description));
- dcc_getfile(NULL, newbuf);
- new_free(&expand);
- new_free(&newbuf);
- }
- }
- doing_multi = 0;
- }
-
-
- static void dcc_getfile (char *command, char *args)
- {
- char *user;
- char *nick;
- char *filename = NULL;
- char *tmp = NULL;
- DCC_list *Client;
- char *fullname = NULL;
- char *passwd = NULL;
- char *argument = NULL;
- int tdcc = 0;
-
- #ifdef PUBLIC_ACCESS
- bitchsay("This command has been disabled on a public access system");
- return;
- #endif
- if (0 == (user = next_arg(args, &args)))
- {
- put_it("%s", convert_output_format("$G %RDCC%n You must supply a nickname for DCC get", NULL, NULL));
- return;
- }
- if (command)
- tdcc = !my_stricmp(command, "TGET");
- if (args && *args)
- {
- if (args && strlen(args) >= 2)
- {
- if (*args != '-' && *(args+1) != 'e')
- filename = next_arg(args, &args);
- else if (args && *args == '-' && *(args+1) == 'e')
- {
- argument = next_arg(args, &args);
- passwd = next_arg(args, &args);
- }
- }
- }
-
- #if defined(WINNT) || defined(__EMX__)
- if (filename)
- convert_unix(filename);
- #endif
- while ((nick = next_in_comma_list(user, &user)))
- {
- if (!nick || !*nick)
- break;
-
- if (!(Client = dcc_searchlist(filename, nick, DCC_FILEREAD, 0, NULL, NULL, 0)))
- {
- if (filename)
- put_it("%s", convert_output_format("$G %RDCC%n No file ($0) offered in SEND mode by $1", "%s %s", filename, nick));
- else
- put_it("%s", convert_output_format("$G %RDCC%n No file offered in SEND mode by $0", "%s", nick));
- continue;
- }
- if ((Client->flags & DCC_ACTIVE) || (Client->flags & DCC_WAIT))
- {
- put_it("%s", convert_output_format("$G %RDCC%n A previous DCC get:$0 to $0 exists", "%s %s", filename, nick));
- continue;
- }
- Client->flags |= DCC_TWOCLIENTS;
- Client->bytes_sent = Client->bytes_read = 0L;
-
- if (passwd)
- Client->encrypt = m_strdup(passwd);
-
- if (!dcc_open(Client))
- continue;
- if (get_string_var(DCC_DLDIR_VAR))
- malloc_sprintf(&tmp, "%s/%s", get_string_var(DCC_DLDIR_VAR), Client->description);
- else
- tmp = m_strdup(Client->description);
- if (!(fullname = expand_twiddle(tmp)))
- malloc_strcpy(&fullname, tmp);
-
- #if defined(WINNT) || defined(__EMX__)
- if (-1 == (Client->file = open(fullname, O_WRONLY | O_TRUNC | O_CREAT | O_BINARY/*, 0644*/)))
- #else
- if (-1 == (Client->file = open(fullname, O_WRONLY | O_TRUNC | O_CREAT, 0644)))
- #endif
- {
- put_it("%s", convert_output_format("$G %RDCC%n Unable to open $0: $1-", "%s %s", fullname, errno?strerror(errno):"Unknown"));
- if (dcc_active_count) dcc_active_count--;
- Client->flags |= DCC_DELETE;
- }
- new_free(&fullname);
- new_free(&tmp);
- }
- }
-
-
- void dcc_regetfile(char *command, char *args)
- {
- char *user;
- char *nick;
- char *passwd = NULL;
- char *tmp = NULL;
- char *filename = NULL;
- DCC_list *Client;
- char *fullname = NULL;
- struct stat buf;
- int tdcc = 0;
-
- #ifdef PUBLIC_ACCESS
- bitchsay("This command has been disabled on a public access system");
- return;
- #endif
- if (0 == (user = next_arg(args, &args)))
- {
- put_it("%s", convert_output_format("$G %RDCC%n You must supply a nickname for DCC get", NULL, NULL));
- return;
- }
- if (command)
- tdcc = !my_stricmp(command, "TREGET");
-
- while (args && *args)
- {
- if (args && strlen(args) >= 2)
- {
- if (!my_strnicmp(args, "-e", 2))
- {
- next_arg(args, &args);
- passwd = next_arg(args, &args);
- }
- else
- filename = next_arg(args, &args);
- }
- }
-
- #if defined(WINNT) || defined(__EMX__)
- if (filename)
- convert_unix(filename);
- #endif
- while ((nick = next_in_comma_list(user, &user)))
- {
- if (!nick || !*nick)
- break;
- if (!(Client = dcc_searchlist(filename, nick, DCC_REGETFILE, 0, NULL, NULL, 0)))
- {
- if (filename)
- put_it("%s", convert_output_format("$G %RDCC%n No file ($0) offered in RESEND mode by $1", "%s %s", filename, nick));
- else
- put_it("%s", convert_output_format("$G %RDCC%n No file offered in RESEND mode by $0", "%s", nick));
- continue;
- }
- if ((Client->flags & DCC_ACTIVE) || (Client->flags & DCC_WAIT))
- {
- put_it("%s", convert_output_format("$G %RDCC%n A previous DCC reget:$0 to $0 exists", "%s %s", filename, nick));
- continue;
- }
- Client->flags |= DCC_TWOCLIENTS;
- Client->bytes_sent = Client->bytes_read = 0L;
-
- if (get_string_var(DCC_DLDIR_VAR))
- malloc_sprintf(&tmp, "%s/%s", get_string_var(DCC_DLDIR_VAR), Client->description);
- else
- tmp = m_strdup(Client->description);
- if (!(fullname = expand_twiddle(tmp)))
- malloc_strcpy(&fullname, tmp);
-
- if (passwd)
- Client->encrypt = m_strdup(passwd);
-
- if (!dcc_open(Client))
- continue;
- #if defined(WINNT) || defined(__EMX__)
- if (-1 == (Client->file = open(fullname, O_WRONLY | O_CREAT | O_BINARY/*, 0644*/)))
- #else
- if (-1 == (Client->file = open(fullname, O_WRONLY | O_CREAT, 0644)))
- #endif
- {
- put_it("%s", convert_output_format("$G %RDCC%n Unable to open $0: $1-", "%s %s", Client->description, errno?strerror(errno):"Unknown"));
- Client->flags |= DCC_DELETE;
- if (dcc_active_count) dcc_active_count--;
- continue;
- }
-
- /* seek to the end of the file about to be resumed */
- lseek(Client->file, 0, SEEK_END);
-
- /* get the size of our file to be resumed */
- fstat(Client->file, &buf);
-
- Client->transfer_orders.packet_id = DCC_PACKETID;
- Client->transfer_orders.byteoffset = buf.st_size;
- Client->transfer_orders.byteorder = byteordertest();
- #ifndef NON_BLOCKING_CONNECTS
- /* send a packet to the sender with transfer resume instructions */
- send(Client->read, (const char *)&(Client->transfer_orders), sizeof(struct transfer_struct), 0);
- #endif
- new_free(&fullname);
- new_free(&tmp);
- }
- }
-
- extern void register_dcc_offer (char *user, char *type, char *description, char *address, char *port, char *size, char *extra, char *userhost)
- {
- DCC_list * Client;
- int CType;
- char * c = NULL;
- u_long TempLong;
- unsigned TempInt;
- int do_auto = 0; /* used in dcc chat collisions */
- int do_autog = 1;
- long packets = 0;
-
- #if defined(WINNT) || defined(__EMX__)
- if ( (c = strrchr(description, '/')) || (c = strrchr(description, '\\')))
- #else
- if ((c = strrchr(description, '/')))
- #endif
- description = c + 1;
- if ('.' == *description)
- *description = '_';
-
- message_from(NULL, LOG_DCC);
- if (size && *size)
- {
- filesize = my_atol(size);
- packets = filesize / dccBlockSize() + 1;
- }
- else
- packets = filesize = 0;
-
- if (!my_stricmp(type, "CHAT"))
- CType = DCC_CHAT;
- else if (!my_stricmp(type, "BOT"))
- CType = DCC_BOTMODE;
- else if (!my_stricmp(type, "SEND"))
- CType = DCC_FILEREAD;
- else if (!my_stricmp(type, "RESEND"))
- CType = DCC_REGETFILE;
- else if (!my_stricmp(type, "TRESEND"))
- CType = DCC_TDCC|DCC_REGETFILE;
- else if (!my_stricmp(type, "TSEND"))
- CType = DCC_TDCC|DCC_FILEREAD;
- #ifdef FTP_XMIT
- else if (!my_stricmp(type, "XMIT"))
- {
- dcc_xmitget(user, description, address, port);
- return;
- }
- #endif
- #ifdef MIRC_BROKEN_DCC_RESUME
- else if (!my_stricmp(type, "RESUME"))
- {
- /*
- * Dont be deceieved by the arguments we're passing it.
- * The arguments are "out of order" because MIRC doesnt
- * send them in the traditional order. Ugh.
- */
- dcc_getfile_resume_demanded(user, description, address, port);
- return;
- }
- else if (!my_stricmp(type, "ACCEPT"))
- {
- /*
- * See the comment above.
- */
- dcc_getfile_resume_start (user, description, address, port);
- return;
- }
- #endif
- else
- {
- put_it("%s", convert_output_format("$G %RDCC%n Unknown DCC $0 ($1) recieved from $2", "%s %s %s", type, description, user));
- message_from(NULL, LOG_CRAP);
- return;
- }
-
- Client = dcc_searchlist(description, user, CType, 1, NULL, NULL, -1);
- filesize = 0;
-
- if (extra && *extra)
- Client->cksum = m_strdup(extra);
-
- if (Client->flags & DCC_WAIT)
- {
- Client->flags |= DCC_DELETE;
- if (DCC_CHAT == CType)
- {
- Client = dcc_searchlist(description, user, CType, 1, NULL, NULL, -1);
- do_auto = 1;
- }
- else
- {
-
- put_it("%s", convert_output_format("$G %RDCC%n $0 collision for $1:$2", "%s %s %s", type, user, description));
- send_ctcp(CTCP_NOTICE, user, CTCP_DCC, "DCC %s collision occured while connecting to %s (%s)", type, nickname, description);
- message_from(NULL, LOG_CRAP);
- return;
- }
- }
- if (Client->flags & DCC_ACTIVE)
- {
- put_it("%s", convert_output_format("$G %RDCC%n Recieved DCC $0 request from $1 while previous session active", "%s %s", type, user));
- message_from(NULL, LOG_CRAP);
- return;
- }
- Client->flags |= DCC_OFFER;
-
- TempLong = strtoul(address, NULL, 10);
- Client->remote.s_addr = htonl(TempLong);
- TempInt = (unsigned) strtoul(port, NULL, 10);
- Client->remport = htons(TempInt);
-
- if (TempInt < 1024)
- {
- put_it("%s", convert_output_format("$G %RDCC%n $0 ($1) request from $2 rejected", "%s %s %s", type, description, user));
- Client->flags |= DCC_DELETE;
- message_from(NULL, LOG_CRAP);
- return;
- }
- if (userhost)
- Client->userhost = m_strdup(userhost);
- #ifdef HACKED_DCC_WARNING
- /* This right here compares the hostname from the userhost stamped
- * on the incoming privmsg to the address stamped in the handshake.
- * We do not automatically reject any discrepencies, but warn the
- * user instead to be cautious.
- */
- {
- char tmpbuf[128];
- char *fromhost;
- u_32int_t compare, compare2;
- u_32int_t compare3, compare4;
- struct hostent *hostent_fromhost;
-
- strncpy(tmpbuf, FromUserHost, 127);
- fromhost = strchr(tmpbuf, '@');
- fromhost++;
- alarm(1); /* dont block too long... */
- hostent_fromhost = gethostbyname(fromhost);
- alarm(0);
- if (!hostent_fromhost)
- {
- yell("Incoming handshake has an address [%s] that could not be figured out!", fromhost);
- yell("Please use caution in deciding whether to accept it or not");
- }
- else
- {
- compare = *((u_32int_t *)hostent_fromhost->h_addr_list[0]);
- compare2 = inet_addr(fromhost);
- compare3 = htonl(0x00000000);
- compare4 = htonl(0xffffffff);
- if (((compare != Client->remote.s_addr) &&
- (compare2 != Client->remote.s_addr)))
- {
- say("WARNING: Fake dcc handshake detected! [%lx]",Client->remote.s_addr);
- say("Unless you know where this dcc request is coming from");
- say("It is recommended you ignore it!");
- do_auto = do_autog = 0;
- }
- if (compare3 == Client->remote.s_addr || compare4 == Client->remote.s_addr)
- {
- yell("WARNING: Fake dcc handshake detected! [%lx]",(unsigned long)Client->remote.s_addr);
- Client->flags = DCC_DELETE;
- message_from(NULL, LOG_CRAP);
- return;
- }
- #if 0
- /* this doesn't quite work properly. a check for DCC_CHAT would be appropriate */
- if (Client->filesize < 1)
- {
- yell("Danger, Will Robinson! Null-file detected!");
- yell("It is highly recommended you ignore this file.");
- return;
- }
- #endif
- }
- }
- #endif
- if ((u_long) 0 == TempLong || 0 == Client->remport)
- {
- yell("DCC handshake from %s ignored becuase it had an null port or address", user);
- Client->flags = DCC_DELETE;
- message_from(NULL, LOG_CRAP);
- return;
- }
- if (((Client->flags & DCC_TYPES) == DCC_FILEREAD) && ((Client->flags & DCC_TYPES) != DCC_REGETFILE))
- {
- struct stat statit;
- char *tmp = NULL, *p;
- malloc_sprintf(&tmp, "%s/%s", get_string_var(DCC_DLDIR_VAR), Client->description);
- p = expand_twiddle(tmp);
- if ( !dcc_overwrite_var && get_int_var(DCC_AUTOGET_VAR) && ((do_autog = stat(p, &statit)) == 0) )
- {
- if (!get_int_var(DCC_AUTORENAME_VAR))
- /* the file exists. warning is generated */
- put_it("%s", convert_output_format("$G %RDCC%n Warning: File $0 exists: use /DCC rename if you dont want to overwrite", "%s", p));
- else
- {
- rename_file(p, &Client->description);
- put_it("%s", convert_output_format("$G %RDCC%n Warning: File $0 renamed: $1", "%s %s", p, Client->description));
- description = Client->description;
- do_autog = 1;
- }
- }
- new_free(&tmp); new_free(&p);
- }
- if (do_auto)
- {
- if (do_hook(DCC_CONNECT_LIST,"%s CHAT %s",user, "already requested connecting"))
- put_it("%s", convert_output_format(fget_string_var(FORMAT_DCC_CONNECT_FSET),
- "%s %s %s %s %s %d", update_clock(GET_TIME), "CHAT", user,
- " ", "already requested connecting...", 0));
- dcc_chat(NULL, user);
- }
- else if (do_hook(DCC_REQUEST_LIST,"%s %s %s %d",user, type, description, Client->filesize))
- {
- if (!dcc_quiet)
- {
-
- char buf[40];
- sprintf(buf, "%2.4g",_GMKv(Client->filesize));
- if (Client->filesize)
- put_it("%s", convert_output_format(fget_string_var(FORMAT_DCC_REQUEST_FSET),
- "%s %s %s %s %s %s %d %s %s",
- update_clock(GET_TIME),type,description,user, FromUserHost,
- inet_ntoa(Client->remote),ntohs(Client->remport),
- _GMKs(Client->filesize), buf));
- else
- put_it("%s", convert_output_format(fget_string_var(FORMAT_DCC_REQUEST_FSET),
- "%s %s %s %s %s %s %d", update_clock(GET_TIME),type,description,
- user, FromUserHost,inet_ntoa(Client->remote),ntohs(Client->remport)));
-
- }
- if (CType == DCC_CHAT)
- {
- if (get_int_var(BOT_MODE_VAR) && find_user_level(Client->user, FromUserHost, "*"))
- {
- dcc_open(Client);
- message_from(NULL, LOG_CRAP);
- return;
- }
- else
- {
- bitchsay("Type /chat to answer or /nochat to close");
- last_chat_req = m_strdup(user);
- }
- }
- }
-
- if (CType == DCC_BOTMODE && get_string_var(BOT_PASSWD_VAR))
- {
- if (((Client->encrypt && !strcmp(get_string_var(BOT_PASSWD_VAR), Client->encrypt))) || !Client->encrypt)
- dcc_open(Client);
- message_from(NULL, LOG_CRAP);
- return;
- }
- if ((get_int_var(DCC_AUTOGET_VAR) || (!get_int_var(DCC_AUTOGET_VAR) && find_name_in_genericlist(user, dcc_no_flood, DCC_HASHSIZE, 0))) &&
- (Client->filesize/1024 < get_int_var(DCC_MAX_AUTOGET_SIZE_VAR))
- && ((CType & DCC_TYPES) == DCC_FILEREAD || (CType & DCC_TYPES) == DCC_REGETFILE))
- {
- char *thebuf = NULL;
- if (!Client->filesize)
- {
- put_it("%s", convert_output_format("$G %RDCC Caution Filesize is 0!! No Autoget", NULL, NULL));
- message_from(NULL, LOG_CRAP);
- return;
- }
- malloc_sprintf(&thebuf, "%s %s", user, description);
- if ((((CType & DCC_TYPES) == DCC_REGETFILE) || do_autog) && !dcc_quiet)
- {
- char *prompt;
- prompt = m_strdup(convert_output_format(get_string_var(CDCC_PROMPT_VAR), NULL, NULL));
- put_it("%s", convert_output_format("$3- Auto-$0ting file %C$1%n from %K[%C$2%K]", "%s %s %s %s", ((CType & DCC_TYPES)== DCC_REGETFILE) ? (CType & DCC_TDCC?"treget":"reget"):(CType & DCC_TDCC?"tget":"get"), description, user, prompt));
- new_free(&prompt);
- }
- if (do_autog)
- {
- if ((CType & DCC_TYPES) == DCC_REGETFILE)
- dcc_regetfile(type, thebuf);
- else
- dcc_getfile(type, thebuf);
- }
- new_free(&thebuf);
- }
- message_from(NULL, LOG_CRAP);
- return;
- }
-
- static void process_incoming_chat (DCC_list *Client)
- {
- struct sockaddr_in remaddr;
- int sra;
- char tmp[MAX_DCC_BLOCK_SIZE*4 + 1];
- char tmp2[MAX_DCC_BLOCK_SIZE*4 + 1];
- char *s = NULL, *bufptr = NULL;
- char *buf = NULL;
- u_32int_t bytesread;
- int type = Client->flags & DCC_TYPES;
-
- if (Client->flags & DCC_WAIT)
- {
- sra = sizeof(struct sockaddr_in);
- Client->write = accept(Client->read, (struct sockaddr *) &remaddr, &sra);
- Client->read = new_close(Client->read);
- if ((Client->read = Client->write) > 0)
- new_open(Client->read);
- else
- {
- put_it("%s", convert_output_format("$G %RDCC error: accept() failed. punt!!", NULL, NULL));
- Client->flags |= DCC_DELETE;
- return;
- }
- Client->flags &= ~DCC_WAIT;
- Client->flags |= DCC_ACTIVE;
- if (do_hook(DCC_CONNECT_LIST, "%s CHAT %s %d", Client->user,
- inet_ntoa(remaddr.sin_addr), ntohs(remaddr.sin_port)))
- put_it("%s", convert_output_format(fget_string_var(FORMAT_DCC_CONNECT_FSET),
- "%s %s %s %s %s %d", update_clock(GET_TIME),
- type == DCC_BOTMODE ? "BOT":"CHAT",
- Client->user, Client->userhost?Client->userhost:"u@h",
- inet_ntoa(remaddr.sin_addr),ntohs(remaddr.sin_port)));
- if ((type == DCC_BOTMODE) && Client->encrypt)
- new_free(&Client->encrypt);
- get_time(&Client->starttime);
- return;
- }
- s = Client->buffer;
- bufptr = tmp;
-
- bytesread = dgets(bufptr, Client->read, 1);
- switch (bytesread)
- {
- case -1:
- {
- char *real_tmp = ((dgets_errno == -1) ? "Remote End Closed Connection" : strerror(dgets_errno));
- if (do_hook(DCC_LOST_LIST, "%s CHAT %s", Client->user, real_tmp))
- put_it("%s", convert_output_format(fget_string_var(FORMAT_DCC_ERROR_FSET),
- "%s %s %s %s", update_clock(GET_TIME),
- type == DCC_BOTMODE? "BOT":"CHAT",
- Client->user, real_tmp));
- Client->flags |= DCC_DELETE;
- return;
- }
- case 0:
- break;
- default:
- {
- char userhost[BIG_BUFFER_SIZE+1];
- char equal_nickname[NICKNAME_LEN+4];
-
- new_free(&Client->buffer);
- if (tmp[strlen(tmp) - 1] == '\n')
- tmp[strlen(tmp) - 1] = 0;
- my_decrypt(tmp, strlen(tmp), Client->encrypt);
- Client->bytes_read += bytesread;
- message_from(Client->user, LOG_DCC);
- malloc_strcpy(&buf, tmp);
-
- #undef CTCP_REPLY
- #define CTCP_MESSAGE "CTCP_MESSAGE "
- #define CTCP_MESSAGE_LEN strlen(CTCP_MESSAGE)
- #define CTCP_REPLY "CTCP_REPLY "
- #define CTCP_REPLY_LEN strlen(CTCP_REPLY)
-
- #ifndef BITCHX_LITE
- if ((Client->flags & DCC_TYPES) == DCC_BOTMODE)
- {
- if (Client->read > -1)
- handle_dcc_bot(Client->read, buf);
- }
- else
- {
- if (*buf == '.')
- {
- if (!check_tcl_dcc(buf+1, Client->user, Client->userhost?Client->userhost:"", Client->read, Client))
- dcc_printf(Client->write, "Unknown command\n");
- }
- else
- #endif
- {
- if (!Client->userhost)
- {
- strcpy(userhost, "Unknown@");
- strcat(userhost, inet_ntoa(remaddr.sin_addr));
- FromUserHost = userhost;
- }
- else
- FromUserHost = Client->userhost;
-
- strncpy(equal_nickname, "=", NICKNAME_LEN);
- strncat(equal_nickname, Client->user, NICKNAME_LEN);
- if (!strncmp(tmp, CTCP_MESSAGE, CTCP_MESSAGE_LEN))
- {
- strcpy(tmp2, tmp);
- strcpy(tmp, do_ctcp(equal_nickname, get_server_nickname(from_server), stripansicodes(tmp2 + CTCP_MESSAGE_LEN)));
- if (!*tmp)
- break;
- }
- else if (!strncmp(tmp, CTCP_REPLY, CTCP_REPLY_LEN) || *tmp == CTCP_DELIM_CHAR)
- {
- strcpy(tmp2, tmp);
- strcpy(tmp, do_notice_ctcp(equal_nickname, get_server_nickname(from_server), stripansicodes(tmp2 + ((*tmp2 == CTCP_DELIM_CHAR) ? 0 : CTCP_REPLY_LEN))));
- if (!*tmp)
- break;
- }
- #ifndef BITCHX_LITE
- else if (Client->in_dcc_chat)
- {
- handle_tcl_chan(Client->read, Client->user, Client->userhost, tmp);
- break;
- }
- #endif
- if (do_hook(DCC_CHAT_LIST, "%s %s", Client->user, tmp))
- {
- addtabkey(equal_nickname, "msg", 0);
- put_it("%s", convert_output_format(fget_string_var(FORMAT_DCC_CHAT_FSET),
- "%s %s %s %s", update_clock(GET_TIME), Client->user, Client->userhost?Client->userhost:"u@h", tmp));
- add_last_type(&last_dcc[0], MAX_LAST_MSG, Client->user, NULL, FromUserHost, tmp);
- }
- FromUserHost = empty_string;
- }
- #ifndef BITCHX_LITE
- }
- #endif
- }
- }
- message_from(NULL, LOG_CRAP);
- new_free(&buf);
- }
-
- static void process_incoming_listen (DCC_list *Client)
- {
- struct sockaddr_in remaddr;
- int sra;
- char FdName[10];
- DCC_list *NewClient;
- int new_socket;
- struct hostent *hp;
- #if defined(__linux__) || defined(__sgi)
- const char *Name;
- #else
- char *Name;
- #endif
-
- sra = sizeof(struct sockaddr_in);
- new_socket = accept(Client->read, (struct sockaddr *) &remaddr, &sra);
- if (new_socket < 0)
- {
- put_it("%s", convert_output_format("$G %RDCC error: accept() failed. punt!!", NULL, NULL));
- return;
- }
- if (0 != (hp = gethostbyaddr((char *)&remaddr.sin_addr,
- sizeof(remaddr.sin_addr), remaddr.sin_family)))
- Name = hp->h_name;
- else
- Name = inet_ntoa(remaddr.sin_addr);
- sprintf(FdName, "%d", new_socket);
- NewClient = dcc_searchlist((char *)Name, FdName, DCC_RAW, 1, NULL, NULL, 0);
-
- get_time(&NewClient->starttime);
-
- NewClient->read = NewClient->write = new_socket;
- new_open(NewClient->read);
-
- NewClient->remote = remaddr.sin_addr;
- NewClient->remport = remaddr.sin_port;
- NewClient->flags |= DCC_ACTIVE;
- NewClient->bytes_read = NewClient->bytes_sent = 0L;
- if (do_hook(DCC_RAW_LIST, "%s %s N %d", NewClient->user,
- NewClient->description,
- Client->write))
- if (do_hook(DCC_CONNECT_LIST,"%s RAW %s %d", NewClient->user,
- NewClient->description,
- Client->write))
- put_it("%s", convert_output_format(fget_string_var(FORMAT_DCC_CONNECT_FSET),
- "%s %s %s %s %s %d", update_clock(GET_TIME),
- "RAW", NewClient->user,
- Client->userhost? Client->userhost:"u@h",
- NewClient->description, Client->write));
- }
-
- static void process_incoming_raw (DCC_list *Client)
- {
- char tmp[MAX_DCC_BLOCK_SIZE + 1];
- char *s, *bufptr;
- u_32int_t bytesread;
- int len = 0;
-
- s = Client->buffer;
- bufptr = tmp;
- if (s && *s)
- {
- len = strlen(s);
- if (len > MAX_DCC_BLOCK_SIZE - 1)
- {
- put_it("%s", convert_output_format("$G %RDCC raw buffer overrun. Data lost", NULL, NULL));
- new_free(&Client->buffer);
- }
- else
- {
- strncpy(tmp, s, len);
- bufptr += len;
- }
- }
- switch(bytesread = dgets(bufptr, Client->read, 0))
- {
- case -1:
- {
- if (do_hook(DCC_RAW_LIST, "%s %s C", Client->user, Client->description))
- if (do_hook(DCC_LOST_LIST,"%s RAW %s", Client->user, Client->description))
- put_it("%s", convert_output_format(fget_string_var(FORMAT_DCC_ERROR_FSET), "%s %s %s %s", update_clock(GET_TIME), "RAW", Client->user, Client->description));
- Client->flags |= DCC_DELETE;
- return;
- }
- case 0:
- default:
- {
- new_free(&Client->buffer);
- if (tmp[strlen(tmp)-1] == '\n')
- tmp[strlen(tmp) - 1] = '\0';
- Client->bytes_read += bytesread;
- if (Client->dcc_handler)
- (Client->dcc_handler)(Client, tmp);
- else
- {
- if (do_hook(DCC_RAW_LIST, "%s %s D %s", Client->user, Client->description, tmp))
- say("Raw data on %s from %s: %s", Client->user, Client->description, tmp);
- }
- return;
- }
- }
- }
-
-
- /* Now that ive mucked this function up, i should go back and fix it. */
- static void process_outgoing_file (DCC_list *Client, int readwaiting)
- {
- struct sockaddr_in remaddr;
- int sra;
- char tmp[MAX_DCC_BLOCK_SIZE+1];
- u_32int_t bytesrecvd = 0;
- int bytesread = 0;
- char *Type;
- unsigned char packet[BIG_BUFFER_SIZE/8];
- struct transfer_struct *received;
- int tdcc = 0;
-
- Type = dcc_types[Client->flags & DCC_TYPES];
- tdcc = Client->flags & DCC_TDCC;
-
- if (Client->flags & DCC_WAIT)
- {
- sra = sizeof(struct sockaddr_in);
- Client->write = accept(Client->read, (struct sockaddr *) &remaddr, &sra);
- if ((Client->flags & DCC_RESENDOFFER) == DCC_RESENDOFFER)
- {
- recv(Client->write, packet, sizeof(struct transfer_struct), 0);
- received = (struct transfer_struct *)packet;
- if (byteordertest() != received->byteorder)
- {
- /* the packet sender orders bytes differently than us,
- * reverse what they sent to get the right value
- */
- Client->transfer_orders.packet_id =
- ((received->packet_id & 0x00ff) << 8) |
- ((received->packet_id & 0xff00) >> 8);
-
- Client->transfer_orders.byteoffset =
- ((received->byteoffset & 0xff000000) >> 24) |
- ((received->byteoffset & 0x00ff0000) >> 8) |
- ((received->byteoffset & 0x0000ff00) << 8) |
- ((received->byteoffset & 0x000000ff) << 24);
- }
- else
- memcpy(&Client->transfer_orders,packet,sizeof(struct transfer_struct));
-
- if (Client->transfer_orders.packet_id != DCC_PACKETID)
- put_it("%s", convert_output_format("$G %RDCC%n reget packet is invalid!!", NULL, NULL));
- else
- put_it("%s", convert_output_format("$G %RDCC%n reget starting at $0", "%d", Client->transfer_orders.byteoffset));
- }
-
- Client->read = new_close(Client->read);
-
- if ((Client->read = Client->write) >= 0)
- new_open(Client->read);
- else
- {
- put_it("%s", convert_output_format("$G %RDCC error: accept() failed. punt!!", NULL, NULL));
-
- Client->flags |= DCC_DELETE;
- if (get_to_from(Type) != -1 && dcc_active_count)
- dcc_active_count--;
- return;
- }
- #if 0
- #if defined(NON_BLOCKING_CONNECTS)
- if (get_int_var(DCC_FAST_VAR) || (Client->flags & DCC_TDCC))
- set_non_blocking(Client->write);
- #endif
- #endif
- Client->flags &= ~DCC_WAIT;
- Client->flags |= DCC_ACTIVE;
- Client->eof = 0;
- get_time(&Client->starttime);
- #if defined(WINNT) || defined(__EMX__)
- if ((Client->file = open(Client->description, O_RDONLY | O_BINARY)) == -1)
- #else
- if ((Client->file = open(Client->description, O_RDONLY)) == -1)
- #endif
- {
- put_it("%s", convert_output_format("$G %RDCC%n Unable to open $0: $1-", "%s %s", Client->description, errno ? strerror(errno) : "Unknown Host"));
- Client->read = new_close(Client->read);
- Client->write = new_close(Client->write);
- if (get_to_from(Type) != -1 && dcc_active_count)
- dcc_active_count--;
- Client->flags |= DCC_DELETE;
- return;
- }
- if ((Client->flags & DCC_RESENDOFFER) == DCC_RESENDOFFER)
- {
- lseek(Client->file, Client->transfer_orders.byteoffset, SEEK_SET);
- errno = 0;
- if (do_hook(DCC_CONNECT_LIST,"%s %s %s %d",Client->user, tdcc?"TRESEND":"SEND",
- inet_ntoa(remaddr.sin_addr), ntohs(remaddr.sin_port)))
- if (!dcc_quiet)
- put_it("%s", convert_output_format(fget_string_var(FORMAT_DCC_CONNECT_FSET),
- "%s %s %s %s %s %d %d", update_clock(GET_TIME), tdcc?"TRESEND":"RESEND",
- Client->user, Client->userhost?Client->userhost:"u@h", inet_ntoa(remaddr.sin_addr),
- ntohs(remaddr.sin_port), Client->transfer_orders.byteoffset));
- }
- else
- {
- if (do_hook(DCC_CONNECT_LIST,"%s %s %s %d %s %d",Client->user, tdcc?"TSEND":"SEND",
- inet_ntoa(remaddr.sin_addr), ntohs(remaddr.sin_port), Client->description, Client->filesize))
- if (!dcc_quiet)
- put_it("%s", convert_output_format(fget_string_var(FORMAT_DCC_CONNECT_FSET),
- "%s %s %s %s %s %d %d", update_clock(GET_TIME), tdcc?"TSEND":"SEND",
- Client->user, Client->userhost?Client->userhost:"u@h", inet_ntoa(remaddr.sin_addr),
- ntohs(remaddr.sin_port), Client->transfer_orders.byteoffset));
- if (Client->transfer_orders.byteoffset)
- lseek(Client->file, Client->transfer_orders.byteoffset, SEEK_SET);
- }
- }
- else if (readwaiting)
- {
- if (!(Client->flags & DCC_TDCC))
- {
- if (read(Client->read, (char *)&bytesrecvd, sizeof(u_32int_t)) < sizeof(u_32int_t))
- {
- if (do_hook(DCC_LOST_LIST,"%s SEND %s CONNECTION LOST",
- Client->user, Client->description))
- put_it("%s", convert_output_format(fget_string_var(FORMAT_DCC_ERROR_FSET), "%s %s %s %s", update_clock(GET_TIME), "SEND", Client->user, Client->description));
- if (get_to_from(Type) != -1 && dcc_active_count)
- dcc_active_count--;
- Client->flags |= DCC_DELETE;
- dcc_update_stats(Client);
- return;
- }
- else if (ntohl(bytesrecvd) != Client->bytes_sent)
- return;
- }
- else
- return;
- /* CDE do we just return here? */
- }
-
- if ((bytesread = read(Client->file, tmp, dccBlockSize())) > 0)
- {
- my_encrypt(tmp, bytesread, Client->encrypt);
- send(Client->write, tmp, bytesread, 0);
- #if 0
- if ((write(Client->write, tmp, bytesread)) == -1)
- {
- yell("outbound write failed");
- Client->flags |= DCC_DELETE;
- return;
- }
- #endif
- Client->packets_transfer++;
- Client->bytes_sent += bytesread;
- update_transfer_buffer("");
- if (!(Client->packets_transfer % 20))
- update_all_status(current_window, NULL, 0);
- }
- else if (!readwaiting)
- {
- if (!(Client->flags & DCC_TDCC))
- Client->eof = 1;
- else
- DCC_close_filesend(Client, "TSEND");
- } else
- DCC_close_filesend(Client, tdcc?"TSEND":"SEND");
- }
-
- static void process_incoming_file (DCC_list *Client)
- {
- char tmp[MAX_DCC_BLOCK_SIZE+1];
- u_32int_t bytestemp;
- int bytesread;
- char *Type;
- int tdcc = 0;
-
- tdcc = Client->flags & DCC_TDCC;
- Type = dcc_types[Client->flags & DCC_TYPES];
-
- if ((bytesread = read(Client->read, tmp, MAX_DCC_BLOCK_SIZE)) <= 0)
- {
- if (Client->bytes_read + Client->transfer_orders.byteoffset < Client->filesize)
- put_it("%s", convert_output_format("$G %RDCC get to $0 lost: Remote peer closed connection", "%s", Client->user));
- DCC_close_filesend(Client, tdcc?"TGET":"GET");
- }
- else
- {
- my_decrypt(tmp, bytesread, Client->encrypt);
- if ((write(Client->file, tmp, bytesread)) == -1)
- {
- yell("write to local file failed");
- Client->flags |= DCC_DELETE;
- return;
- }
-
- Client->bytes_read += bytesread;
- if (!(Client->flags & DCC_TDCC))
- {
- bytestemp = htonl(Client->bytes_read);
- send(Client->write, (char *)&bytestemp, sizeof(u_32int_t), 0);
- #if 0
- if ((write(Client->write, (char *)&bytestemp, sizeof(u_32int_t))) == -1)
- {
- yell("write to remote failed");
- Client->flags |= DCC_DELETE;
- return;
- }
- #endif
- }
- Client->packets_transfer++;
-
- /* TAKE THIS OUT IF IT CAUSES PROBLEMS */
- if (Client->filesize)
- {
- if (Client->bytes_read > Client->filesize)
- {
- put_it("%s", convert_output_format("$G %RDCC%n Warning: incoming file is larger than the handshake said", NULL, NULL));
- put_it("%s", convert_output_format("$G %RDCC%n Warning: GET: closing connection", NULL, NULL));
- if (dcc_active_count)
- dcc_active_count--;
- Client->flags |= DCC_DELETE;
- dcc_update_stats(Client);
- update_all_status(current_window, NULL, 0);
- return;
- }
- else if (Client->bytes_read == Client->filesize)
- {
- DCC_close_filesend(Client, tdcc?"TGET":"GET");
- return;
- }
- update_transfer_buffer("");
- if (!(Client->packets_transfer % 20))
- update_all_status(current_window, NULL, 0);
- }
- }
- }
-
- /* flag == 1 means show it. flag == 0 used by redirect (and /ctcp) */
-
- extern void dcc_message_transmit (char *user, char *text, char *text_display, int type, int flag, char *cmd, int check_host)
- {
- DCC_list *Client;
- char tmp[MAX_DCC_BLOCK_SIZE+1];
- int lastlog_level;
- int list = 0;
- int len = 0;
- char *host = NULL;
- char thing = 0;
- *tmp = 0;
- switch(type)
- {
- case DCC_CHAT:
- thing = '=';
- host = "chat";
- list = SEND_DCC_CHAT_LIST;
- break;
- case DCC_RAW:
- if (check_host)
- {
- if (!(host = next_arg(text, &text)))
- {
- put_it("%s", convert_output_format("$G %RDCC%n No host specified for DCC RAW", NULL, NULL));
- return;
- }
- }
- break;
- }
- if (!(Client = dcc_searchlist(host, user, type, 0, NULL, NULL, 1)) || !(Client->flags & DCC_ACTIVE))
- {
- put_it("%s", convert_output_format("$G %RDCC No active $0:$1 connection for $2", "%s %s %s", dcc_types[type], host?host:"(null)", user));
- return;
- }
- lastlog_level = set_lastlog_msg_level(LOG_DCC);
- message_from(Client->user, LOG_DCC);
-
- /*
- * Check for CTCPs... whee.
- */
- if (cmd && *text == CTCP_DELIM_CHAR)
- {
- if (!strcmp(cmd, "PRIVMSG"))
- strmcpy(tmp, "CTCP_MESSAGE ", dccBlockSize());
- else
- strmcpy(tmp, "CTCP_REPLY ", dccBlockSize());
- }
-
- strmcat(tmp, text, dccBlockSize()-3);
- strmcat(tmp, "\n", dccBlockSize()-2);
-
- len = strlen(tmp);
- my_encrypt(tmp, len, Client->encrypt);
- write(Client->write, tmp, len);
- Client->bytes_sent += len;
-
- if (flag && type != DCC_RAW)
- {
- if (!my_strnicmp(tmp, ".chat", strlen(tmp)))
- Client->in_dcc_chat = 1;
- if (do_hook(list, "%s %s", Client->user, text_display ? text_display : text))
- put_it("%s", convert_output_format(fget_string_var(FORMAT_SEND_DCC_CHAT_FSET), "%c %s %s", thing, Client->user, text_display?text_display:text));
- }
- set_lastlog_msg_level(lastlog_level);
- message_from(NULL, LOG_CRAP);
- return;
- }
-
- extern void dcc_chat_transmit (char *user, char *text, char *orig, char *type)
- {
- dcc_message_transmit(user, text, orig, DCC_CHAT, 1, type, 0);
- }
-
- extern void dcc_raw_transmit (char *user, char *text, char *type)
- {
- dcc_message_transmit(user, text, NULL, DCC_RAW, 0, type, 0);
- }
-
- extern void dcc_bot_transmit (char *user, char *text, char *type)
- {
- dcc_message_transmit(user, text, NULL, DCC_BOTMODE, 0, type, 1);
- }
-
- extern void dcc_chat_transmit_quiet (char *user, char *text, char *type)
- {
- dcc_message_transmit(user, text, NULL, DCC_CHAT, 0, type, 0);
- }
-
- extern void dcc_chat_crash_transmit (char *user, char *text)
- {
- char buffer[20000];
- DCC_list *Client;
- char *host = "chat";
-
- memset(buffer, ' ', 20000-10);
- buffer[20000-9] = '\n';
- buffer[20000-8] = '\0';
- if (!(Client = dcc_searchlist(host, user, DCC_CHAT, 0, NULL, NULL, 1)) || !(Client->flags&DCC_ACTIVE))
- {
- put_it("%s", convert_output_format("$G %RDCC%n No active DCC $0:$1 connection for $2", "%s %s %s", dcc_types[DCC_CHAT], host?host:"(null)", user));
- return;
- }
- send(Client->write, buffer, strlen(buffer), 0);
- Client->bytes_sent += strlen(buffer);
- return;
- }
-
- static void dcc_send_raw (char *command, char *args)
- {
- char *name;
-
- if (!(name = next_arg(args, &args)))
- {
- put_it("%s", convert_output_format("$G %RDCC%n No name specified for DCC raw", NULL, NULL));
- return;
- }
- dcc_message_transmit(name, args, NULL, DCC_RAW, 1, NULL, 1);
- }
-
- /*
- * dcc_time: Given a time value, it returns a string that is in the
- * format of "hours:minutes:seconds month day year" . Used by
- * dcc_list() to show the start time.
- */
- char *dcc_time (time_t time)
- {
- struct tm *btime;
- char *buf = NULL;
- static char *months[] =
- {
- "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
- };
-
- btime = localtime(&time);
- if (time)
- malloc_sprintf(&buf, "%-2.2d:%-2.2d:%-2.2d %s %-2.2d %d", btime->tm_hour,
- btime->tm_min, btime->tm_sec, months[btime->tm_mon],
- btime->tm_mday, btime->tm_year + 1900);
- return buf;
- }
-
- static char *get_dcc_type (unsigned long flag)
- {
- static char ret[20];
- if (flag & DCC_TDCC)
- {
- switch(flag & DCC_TYPES)
- {
- case DCC_FILEOFFER:
- strcpy(ret, "TSEND");
- break;
- case DCC_FILEREAD:
- strcpy(ret, "TGET");
- break;
- case DCC_RESENDOFFER:
- strcpy(ret, "TRESEND");
- break;
- case DCC_REGETFILE:
- strcpy(ret, "TREGET");
- break;
- }
- }
- else
- strcpy(ret, dcc_types[flag & DCC_TYPES]);
- return ret;
- }
-
- extern void dcc_list (char *command, char *args)
- {
- DCC_list *Client;
- const char *format =
- "%-5.5s%-3.3s %-9.9s %-8.8s %-20.20s %-8.8s %-8.8s %s";
- unsigned flags;
- int count = 0;
- char *filename = NULL;
-
- for (Client = ClientList ; Client != NULL ; Client = Client->next)
- {
- char completed[9];
- char size[9];
- char *stime = NULL;
-
- if (Client->filesize)
- {
- sprintf(completed, "%ld%%",(unsigned long) (Client->bytes_sent?Client->bytes_sent:Client->bytes_read) * 100 / Client->filesize);
- sprintf(size, "%ld", (unsigned long)Client->filesize);
- }
- else
- {
- sprintf(completed, "%ldK", (unsigned long) (Client->bytes_sent ? Client->bytes_sent : Client->bytes_read) / 1024);
- strcpy(size, empty_string);
- }
- stime = Client->starttime.tv_sec ? dcc_time(Client->starttime.tv_sec): "";
- flags = Client->flags;
-
- if (!dcc_paths)
- filename = strrchr(Client->description, '/');
-
- if (!filename)
- filename = Client->description;
-
- if (!count)
- put_it(format, "Type", " ", "Nick", "Status", "Start time", "Size", "Complete", "Arguments");
- put_it(format,
- get_dcc_type(flags & DCC_TYPES),
- Client->encrypt ? "[E]" : "",
- Client->user,
- flags&DCC_DELETE ? "Closed" :
- flags&DCC_ACTIVE ? "Active" :
- flags&DCC_WAIT ? "Waiting" :
- flags&DCC_OFFER ? "Offered" : "Unknown",
- stime, size, completed, filename);
-
- if (stime && *stime)
- new_free(&stime);
- count++;
- }
- }
-
- void dcc_glist(char *command, char *args)
- {
- DCC_list *Client = ClientList;
- char *dformat =
- "#$[2]0 $[6]1%Y$2%n $[11]3 $[25]4 $[7]5 $6";
- char *d1format =
- "#$[2]0 $[6]1%Y$2%n $[11]3 $4 $[11]5 $[10]6 $[7]7 $8-";
- char *c1format =
- "#$[2]0 $[6]1%Y$2%n $[11]3 $4 $[-4]5 $[-4]6 $[-3]7 $[-3]8 $[7]9 $10";
-
- unsigned flags;
- unsigned count= 0;
- int size = 0;
- double barsize = 0.0, perc = 0.0;
- int barlen = BAR_LENGTH;
- char spec[BIG_BUFFER_SIZE+1];
- char *Type;
-
- barlen = BAR_LENGTH;
- barsize = 0.0;
- memset(spec, 0, sizeof(spec)-1);
-
- if (ClientList && do_hook(DCC_HEADER_LIST, "%s %s %s %s %s %s %s", "Dnum","Type","Nick", "Status", "K/s", "File","Encrypt"))
- {
- #ifdef ONLY_STD_CHARS
-
- put_it("%s", convert_output_format("%G# %W|%n %GT%gype %W|%n %GN%gick %W|%n %GP%gercent %GC%gomplete %W|%n %GK%g/s %W|%n %GF%gile", NULL, NULL));
- put_it("%s", convert_output_format("%W---------------------------------------------------------------------------", NULL, NULL));
-
- #else
- put_it("%s", convert_output_format("%G# %W│%n %GT%gype %W│%n %GN%gick %W│%n %GP%gercent %GC%gomplete %W│%n %GK%g/s %W│%n %GF%gile", NULL, NULL));
- put_it("%s", convert_output_format("%K──%n─%W─%n─%K─────%n─%W─%n─%K─────────%n─%W─%n─%K───────────────%n─%W─%n─%K─────%n─%W─%n─%K─────%n─%W─%n─%K────────────────", NULL, NULL));
- #endif
- }
- for (Client = ClientList ; Client != NULL ; Client = Client->next)
- {
- flags = Client->flags & DCC_TYPES;
- if ((flags == DCC_FILEOFFER || flags == DCC_FILEREAD || flags == DCC_RESENDOFFER || flags == DCC_REGETFILE || flags == DCC_FTPGET || flags == DCC_FTPSEND))
- if ((Client->flags & DCC_ACTIVE))
- continue;
- Type = get_dcc_type(flags & DCC_TYPES);
- if (do_hook(DCC_STAT_LIST, "%d %s %s %s %s %s %s",
- Client->dccnum, Type,
- Client->user,
- Client->flags & DCC_OFFER ? "Offer" :
- Client->flags & DCC_DELETE ? "Close" :
- Client->flags & DCC_ACTIVE ? "Active" :
- Client->flags & DCC_WAIT ? "Wait" :
- #ifdef DCC_DCNT_PEND
- Client->flags & DCC_CNCT_PEND ? "Connect" :
- #endif
- "Unknown",
- "N/A", Client->description, Client->encrypt?"E":""))
- {
- time_t u_time = (time_t) time_diff(Client->starttime, get_time(NULL));
- if ((((flags & DCC_TYPES) == DCC_CHAT) || ((flags & DCC_TYPES) == DCC_RAW) || ((flags & DCC_TYPES) == DCC_BOTMODE) || ((flags & DCC_TYPES) == DCC_FTPOPEN)) && (Client->flags & DCC_ACTIVE))
- {
- put_it("%s", convert_output_format(c1format, "%d %s %s %s %s %s %s %s",
- Client->dccnum,
- Type,
- Client->encrypt ? "E" : " ",
- Client->user,
- "Active",
- convert_time(u_time),
- "N/A",
- check_paths(Client->description)));
- }
- else
- {
- put_it("%s", convert_output_format(dformat, "%d %s %s %s %s %s %s",
- Client->dccnum,
- Type,
- Client->encrypt ? "E" : " ",
- Client->user,
-
- Client->flags & DCC_OFFER ? "Offer" :
- Client->flags & DCC_DELETE ? "Close" :
- Client->flags & DCC_ACTIVE ? "Active" :
- Client->flags & DCC_WAIT ? "Wait" :
- #ifdef DCC_DCNT_PEND
- Client->flags & DCC_CNCT_PEND ? "Connect" :
- #endif
- "Unknown",
- "N/A",
- check_paths(Client->description)));
- }
- }
-
- count++;
- }
- for (Client = ClientList ; Client != NULL ; Client = Client->next)
- {
- char kilobytes[100];
- time_t xtime = time(NULL) - Client->starttime.tv_sec;
- double bytes = Client->bytes_read + Client->bytes_sent + Client->transfer_orders.byteoffset,
- sent;
- char stats[80];
- int seconds = 0, minutes = 0;
- int iperc = 0;
- #ifdef ONLY_STD_CHARS
- char *_dcc_offer[12] = {"%K-.........%n", /* 0 */
- "%K-.........%n", /* 10 */
- "%K-=........%n", /* 20 */
- "%K-=*.......%n", /* 30 */
- "%K-=*%1%K=%0%K......%n", /* 40 */
- "%K-=*%1%K=-%0%K.....%n", /* 50 */
- "%K-=*%1%K=-.%0%K....%n", /* 60 */
- "%K-=*%1%K=-. %0%K...%n", /* 70 */
- "%K-=*%1%K=-. %R.%0%K..%n", /* 80 */
- "%K-=*%1%K=-. %R.-%0%K.%n", /* 90 */
- "%K-=*%1%K=-. %R.-=%n", /* 100 */
- ""};
- #else
- char *_dcc_offer[12] = {"%K▒░░░░░░░░░%n", /* 0 */
- "%K▒░░░░░░░░░%n", /* 10 */
- "%K▒▓░░░░░░░░%n", /* 20 */
- "%K▒▓█░░░░░░░%n", /* 30 */
- "%K▒▓█%1%K▓%0%K░░░░░░%n", /* 40 */
- "%K▒▓█%1%K▓▒%0%K░░░░░%n", /* 50 */
- "%K▒▓█%1%K▓▒░%0%K░░░░%n", /* 60 */
- "%K▒▓█%1%K▓▒░ %0%K░░░%n", /* 70 */
- "%K▒▓█%1%K▓▒░ %R░%0%K░░%n", /* 80 */
- "%K▒▓█%1%K▓▒░ %R░▒%0%K░%n", /* 90 */
- "%K▒▓█%1%K▓▒░ %R░▒▓%n", /* 100 */
- ""};
- #endif
- char *bar_end;
- *stats = 0;
- *kilobytes = 0;
- perc = 0.0;
- sent = bytes - Client->transfer_orders.byteoffset;
- flags = Client->flags & DCC_TYPES;
-
- if ((Client->flags & DCC_WAIT || Client->flags & DCC_OFFER) || ((flags & DCC_FILEOFFER)==0) || ((flags & DCC_FILEREAD) == 0) || ((flags & DCC_RESENDOFFER) == 0) || ((flags & DCC_REGETFILE) == 0))
- continue;
-
- sent /= (double)1024.0;
- if (xtime <= 0)
- xtime = 1;
- sprintf(kilobytes, "%2.4g", sent/(double)xtime);
-
- if ((bytes >= 0) && (Client->flags & DCC_ACTIVE))
- {
- if (bytes && Client->filesize >= bytes)
- {
- perc = (100.0 * ((double)bytes) / (double)(Client->filesize));
- if ( perc > 100.0) perc = 100.0;
- else if (perc < 0.0) perc = 0.0;
- seconds = (int) (( (Client->filesize - bytes) / (bytes / xtime)) + 0.5);
- minutes = seconds / 60;
- seconds = seconds - (minutes * 60);
- if (minutes > 999) {
- minutes = 999;
- seconds = 59;
- }
- if (seconds < 0) seconds = 0;
- } else
- seconds = minutes = perc = 0;
-
- iperc = ((int)perc) / 10;
- barsize = ((double) (Client->filesize)) / (double) barlen;
-
- size = (int) ((double) bytes / (double)barsize);
-
- if (Client->filesize == 0)
- size = barlen;
- sprintf(stats, "%4.1f", perc);
- sprintf(spec, "%s %s%s %02d:%02d", _dcc_offer[iperc], stats, "%%", minutes, seconds);
- strcpy(spec, convert_output_format(spec, NULL, NULL));
- }
- Type = get_dcc_type(flags & DCC_TYPES);
- if (do_hook(DCC_STATF_LIST, "%d %s %s %s %s %s %s",
- Client->dccnum, Type,
- Client->user,
- Client->flags & DCC_OFFER ? "Offer" :
- Client->flags & DCC_DELETE ? "Close" :
- Client->flags & DCC_ACTIVE ? "Active" :
- Client->flags & DCC_WAIT ? "Wait" :
- #ifdef DCC_DCNT_PEND
- Client->flags & DCC_CNCT_PEND ? "Connect" :
- #endif
- "Unknown",
- kilobytes, check_paths(Client->description), Client->encrypt?"E":""))
- {
- char *s;
- if (get_int_var(DISPLAY_ANSI_VAR))
- if (!get_int_var(DCC_BAR_TYPE_VAR))
- s = d1format;
- else
- s = dformat;
- else
- s = dformat;
- put_it("%s", convert_output_format(s, "%d %s %s %s %s %s %s",
- Client->dccnum, Type,
- Client->encrypt ? "E":" ",
- Client->user,
- Client->flags & DCC_OFFER ? "Offer" :
- Client->flags & DCC_DELETE ? "Close" :
- Client->flags & DCC_ACTIVE ? ((get_int_var(DISPLAY_ANSI_VAR) && !get_int_var(DCC_BAR_TYPE_VAR)) ? spec : "Active"):
- Client->flags & DCC_WAIT ? "Wait" :
- #ifdef DCC_DCNT_PEND
- Client->flags & DCC_CNCT_PEND ? "Connect" :
- #endif
- "?????",
- kilobytes,
- strip_path(Client->description)));
- }
-
- if (do_hook(DCC_STATF1_LIST, "%s %ld %ld %d %d",
- stats,(unsigned long)bytes, (unsigned long)Client->filesize,
- minutes, seconds) && (!get_int_var(DISPLAY_ANSI_VAR) || get_int_var(DCC_BAR_TYPE_VAR)))
- {
- sprintf(stats, "%4.1f%% (%ld of %ld bytes)", perc, (unsigned long)bytes, (unsigned long)Client->filesize);
- strcpy( spec, "\002[\026");
- sprintf(spec+3, "%*s", size+1, " ");
- bar_end = spec + (strlen(spec));
- sprintf(bar_end, "%*s", barlen-size+1, " ");
- strcat(spec, "\026\002]\002 ETA %02d:%02d");
- memcpy((spec+(((BAR_LENGTH+2) / 2) - (strlen(stats) / 2))), stats, strlen(stats));
- if (size < barlen)
- {
- memmove(bar_end+1, bar_end, strlen(bar_end));
- *bar_end = '\002';
- *(bar_end+1) = 0;
- }
- put_it(spec, minutes, seconds);
- }
- count++;
- }
- if (ClientList && count)
- do_hook(DCC_POST_LIST, "%s %s %s %s %s %s %s", "DCCnum","Type","Nick", "Status", "K/s", "File","Encrypt");
- if (count == 0)
- put_it("%s", convert_output_format("$G %RDCC%n Nothing on DCC list.", NULL, NULL));
- }
-
- static char DCC_reject_type[12];
- static char DCC_reject_description[40];
-
- static void output_reject_ctcp (char *notused, char *nicklist)
- {
- if (nicklist && *nicklist && *DCC_reject_description)
- send_ctcp(CTCP_NOTICE, nicklist, CTCP_DCC,
- "REJECT %s %s", DCC_reject_type, DCC_reject_description);
- strcpy(DCC_reject_description, empty_string);
- strcpy(DCC_reject_type, empty_string);
- }
-
- /* added by Patch */
- void dcc_close_client_num(unsigned int closenum)
- {
- DCC_list *Client, *next;
- unsigned flags;
- char *Type;
- int to_from_idx;
-
- for (Client = ClientList ; Client != NULL ; Client = next)
- {
- flags = Client->flags;
- Type = get_dcc_type(flags & DCC_TYPES);
- /*dcc_types[flags & DCC_TYPES];*/
- to_from_idx = get_to_from(Type);
- next = Client->next;
-
- if (Client->dccnum == closenum)
- {
- if (flags & DCC_DELETE)
- return;
- if ((flags & DCC_WAIT) || (flags & DCC_ACTIVE))
- {
- if (flags & DCC_ACTIVE && to_from_idx != -1)
- dcc_update_stats(Client);
- if (to_from_idx != -1 && dcc_active_count) dcc_active_count--;
- }
-
- if (do_hook(DCC_LOST_LIST, "%s %s %s", Client->user, Type,
- Client->description? Client->description : "<any>"))
- put_it("%s", convert_output_format(fget_string_var(FORMAT_DCC_ERROR_FSET), "%s %s %s %s", update_clock(GET_TIME), Type, Client->user, Client->description));
- dcc_reject_notify(Client->description, Client->user, Type);
- dcc_erase(Client);
- update_transfer_buffer("");
- update_all_status(current_window, NULL, 0);
- return;
- }
- }
-
- put_it("%s", convert_output_format("%RDCC%n CLOSE number $0 does not exist","%d", closenum));
- }
-
- /* added by Patch */
- void
- dcc_close_all(void)
- {
- DCC_list *Client, *next;
- unsigned flags;
- char *Type;
- int to_from_idx;
-
- for (Client = ClientList ; Client != NULL ; Client = next)
- {
- flags = Client->flags;
- Type = get_dcc_type(flags & DCC_TYPES);
- to_from_idx = get_to_from(Type);
- next = Client->next;
-
- if (flags & DCC_DELETE)
- continue;
- if ((flags & DCC_WAIT) || (flags & DCC_ACTIVE))
- {
- if (flags & DCC_ACTIVE && to_from_idx != -1)
- dcc_update_stats(Client);
- if (to_from_idx != -1 && dcc_active_count) dcc_active_count--;
- }
-
- if (do_hook(DCC_LOST_LIST, "%s %s %s", Client->user, Type,
- Client->description? Client->description : "<any>"))
- put_it("%s", convert_output_format(fget_string_var(FORMAT_DCC_ERROR_FSET), "%s %s %s %s", update_clock(GET_TIME), Type, Client->user, Client->description));
- dcc_reject_notify(Client->description, Client->user, Type);
- dcc_erase(Client);
- update_transfer_buffer("");
- update_all_status(current_window, NULL, 0);
- }
- }
-
- /* added by Patch */
- void
- dcc_close_type_all(char *typestr)
- {
- DCC_list *Client, *next;
- unsigned flags;
- char *Type;
- int to_from_idx;
-
- to_from_idx = get_to_from(typestr);
-
- for (Client = ClientList ; Client != NULL ; Client = next)
- {
- flags = Client->flags;
- Type = get_dcc_type(flags & DCC_TYPES);
- next = Client->next;
-
- if (my_stricmp(Type,typestr) == 0)
- {
- if (flags & DCC_DELETE)
- return;
- if ((flags & DCC_WAIT) || (flags & DCC_ACTIVE))
- {
- if (flags & DCC_ACTIVE && to_from_idx != -1)
- dcc_update_stats(Client);
- if (to_from_idx != -1 && dcc_active_count) dcc_active_count--;
- }
- if (do_hook(DCC_LOST_LIST, "%s %s %s", Client->user, Type,
- Client->description? Client->description : "<any>"))
- put_it("%s", convert_output_format(fget_string_var(FORMAT_DCC_ERROR_FSET), "%s %s %s %s", update_clock(GET_TIME), Type, Client->user, Client->description));
- dcc_reject_notify(Client->description, Client->user, Type);
- dcc_erase(Client);
- update_transfer_buffer("");
- update_all_status(current_window, NULL, 0);
- }
- }
- }
-
- /* added by Patch */
- void
- dcc_close_nick_all(char *nickstr)
- {
- DCC_list *Client, *next;
- unsigned flags;
- char *Type;
- int to_from_idx;
-
- for (Client = ClientList ; Client != NULL ; Client = next)
- {
- flags = Client->flags;
- Type = get_dcc_type(flags & DCC_TYPES);
- /*dcc_types[flags & DCC_TYPES];*/
- to_from_idx = get_to_from(Type);
- next = Client->next;
-
- if (my_stricmp(Client->user,nickstr) == 0)
- {
- if (flags & DCC_DELETE)
- return;
- if ((flags & DCC_WAIT) || (flags & DCC_ACTIVE))
- {
- if (flags & DCC_ACTIVE && to_from_idx != -1)
- dcc_update_stats(Client);
- if (to_from_idx != -1 && dcc_active_count) dcc_active_count--;
- }
-
- if (do_hook(DCC_LOST_LIST, "%s %s %s", Client->user, Type,
- Client->description? Client->description : "<any>"))
- put_it("%s", convert_output_format(fget_string_var(FORMAT_DCC_ERROR_FSET), "%s %s %s %s", update_clock(GET_TIME), Type, Client->user, Client->description));
- dcc_reject_notify(Client->description, Client->user, Type);
- dcc_erase(Client);
- update_transfer_buffer("");
- update_all_status(current_window, NULL, 0);
- }
- }
- }
-
- /* added by Patch */
- void
- dcc_close_type_nick_all(char *typestr, char *nickstr)
- {
- DCC_list *Client, *next;
- unsigned flags;
- char *Type;
- int to_from_idx;
-
- to_from_idx = get_to_from(typestr);
-
- for (Client = ClientList ; Client != NULL ; Client = next)
- {
- flags = Client->flags;
- Type = get_dcc_type(flags & DCC_TYPES);
- /*dcc_types[flags & DCC_TYPES];*/
- next = Client->next;
-
- if (my_stricmp(Type,typestr) == 0 &&
- my_stricmp(Client->user,nickstr) == 0)
- {
- if (flags & DCC_DELETE)
- return;
- if ((flags & DCC_WAIT) || (flags & DCC_ACTIVE))
- {
- if (flags & DCC_ACTIVE && to_from_idx != -1)
- dcc_update_stats(Client);
- if (to_from_idx != -1 && dcc_active_count) dcc_active_count--;
- }
- if (do_hook(DCC_LOST_LIST, "%s %s %s", Client->user, Type,
- Client->description? Client->description : "<any>"))
- put_it("%s", convert_output_format(fget_string_var(FORMAT_DCC_ERROR_FSET), "%s %s %s %s", update_clock(GET_TIME), Type, Client->user, Client->description));
- dcc_reject_notify(Client->description, Client->user, Type);
- dcc_erase(Client);
- update_transfer_buffer("");
- update_all_status(current_window, NULL, 0);
- }
- }
- }
-
- /* added by Patch */
- void
- dcc_close_filename(char *filename, char *user, char *Type, int CType)
- {
- DCC_list *Client;
- unsigned flags;
- int to_from_idx;
-
- to_from_idx = get_to_from(Type);
- if ((Client = dcc_searchlist(filename, user, CType, 0, filename, NULL, -1)))
- {
- flags = Client->flags;
- if (flags & DCC_DELETE)
- return;
- if ((flags & DCC_WAIT) || (flags & DCC_ACTIVE))
- {
- if (flags & DCC_ACTIVE && to_from_idx != -1)
- dcc_update_stats(Client);
- if (to_from_idx != -1 && dcc_active_count) dcc_active_count--;
- }
-
- if (do_hook(DCC_LOST_LIST, "%s %s %s", Client->user, Type,
- Client->description? Client->description : "<any>"))
- put_it("%s", convert_output_format(fget_string_var(FORMAT_DCC_ERROR_FSET), "%s %s %s %s", update_clock(GET_TIME), Type, Client->user, Client->description));
- dcc_reject_notify(Client->description, Client->user, Type);
- dcc_erase(Client);
- update_transfer_buffer("");
- update_all_status(current_window, NULL, 0);
- }
- else
- put_it("%s", convert_output_format("$G %RDCC%n No DCC $0:$1 to $2 found","%s %s %s", Type, filename?filename:"(null)",user));
- }
-
- /* completely rewritten by Patch */
- void dcc_close(char *command, char *args)
- {
- char *Type;
- char *user;
- char *description;
- int CType;
- unsigned int closenum;
-
- Type = next_arg(args, &args);
- user = next_arg(args, &args);
- description = next_arg(args, &args);
-
- /*****************************************************************************
- DCC CLOSE #all or #number
- *****************************************************************************/
-
- if (!Type)
- {
- put_it("%s", convert_output_format("$G %RDCC%n You must specify a type|dcc_num for DCC close", NULL, NULL));
- return;
- }
-
- if ((Type[0] == '#' && !user && *(Type+1) && my_atol(Type+1)) || !my_stricmp(Type, "-all"))
- {
- if (!my_stricmp(Type,"-all"))
- {
- dcc_close_all();
- dcc_active_count = 0;
- update_all_status(current_window, NULL, 0);
- return;
- }
-
- closenum = atol(Type+1);
-
- if (closenum == 0)
- {
- put_it("%s", convert_output_format("$G %RDCC%n close invalid number", NULL, NULL));
- return;
- }
-
- dcc_close_client_num(closenum);
- update_all_status(current_window, NULL, 0);
- return;
- }
-
- /*****************************************************************************
- DCC CLOSE SEND|GET|RESEND|REGET|nick #all
- *****************************************************************************/
-
- if (!user)
- {
- put_it("%s", convert_output_format("$G %RDCC%n specify a type and a nick for DCC close", NULL, NULL));
- return;
- }
-
- for (CType = 0; dcc_types[CType] != NULL; CType++)
- if (!my_stricmp(Type, dcc_types[CType])) break;
-
- if (user[0] == '#' && !description && (my_atol(user+1) || my_stricmp(user+1, "all")==0))
- {
- if (my_stricmp(user+1,"all") == 0)
- {
- if (!dcc_types[CType])
- dcc_close_nick_all(Type);
- else
- dcc_close_type_all(Type);
- update_all_status(current_window, NULL, 0);
- return;
- }
- put_it("%s", convert_output_format("$G %RDCC%n close invalid number", NULL, NULL));
- return;
- }
-
- /*****************************************************************************
- DCC CLOSE SEND|GET|RESEND|REGET nick #all|filename
- *****************************************************************************/
-
- if (description && *description == '-')
- {
- if (!my_stricmp(description,"-all"))
- dcc_close_type_nick_all(Type,user);
- else
- put_it("%s", convert_output_format("$G %RDCC%n CLOSE invalid description", NULL, NULL));
- return;
- }
-
- if (dcc_types[CType])
- dcc_close_filename(description, user, Type, CType);
- else
- put_it("%s", convert_output_format("$G %RDCC%n Unknown type [$0]", "%s", dcc_types[CType]));
- }
-
- void dcc_reject_notify(char *description, char *user, char *Type)
- {
- strcpy(DCC_reject_description, description ? description : "(null)");
- if (!my_stricmp(Type, "TSEND"))
- strcpy(DCC_reject_type, "TGET");
- else if (!my_stricmp(Type, "TGET"))
- strcpy(DCC_reject_type, "TSEND");
- else if (!my_stricmp(Type, "TREGET"))
- strcpy(DCC_reject_type, "TRESEND");
- else if (!my_stricmp(Type, "TRESEND"))
- strcpy(DCC_reject_type, "TREGET");
- else if (!my_stricmp(Type, "SEND"))
- strcpy(DCC_reject_type, "GET");
- else if (!my_stricmp(Type, "GET"))
- strcpy(DCC_reject_type, "SEND");
- else if (!my_stricmp(Type, "RESEND"))
- strcpy(DCC_reject_type, "REGET");
- else if (!my_stricmp(Type, "REGET"))
- strcpy(DCC_reject_type, "RESEND");
- else
- strcpy(DCC_reject_type, Type);
- if (*user == '=')
- user++;
- add_ison_to_whois (user, output_reject_ctcp);
- }
-
- extern void dcc_reject (char *from, char *type, char *args)
- {
- DCC_list *Client;
- char *description;
- int CType;
- int tdcc = 0;
-
- upper(type);
- if (*type == 'T' && *(type+1))
- tdcc = 1;
- for (CType = 0; dcc_types[CType] != NULL; CType++)
- if (!strcmp(type+tdcc, dcc_types[CType]))
- break;
-
- if (!dcc_types[CType])
- return;
- if (tdcc)
- CType |= DCC_TDCC;
-
- description = next_arg(args, &args);
-
- if ((Client = dcc_searchlist(NULL, from, CType, 0, description, NULL, -1)))
- {
- if (Client->flags & DCC_DELETE)
- return;
- if (do_hook(DCC_LOST_LIST,"%s %s %s REJECTED", from, type, description ? description : "<any>"))
- put_it("%s", convert_output_format(fget_string_var(FORMAT_DCC_ERROR_FSET), "%s %s %s %s", update_clock(GET_TIME), type, Client->user, Client->description));
- update_transfer_buffer("");
- Client->flags |= DCC_DELETE;
- update_all_status(current_window, NULL, 0);
- #ifdef WANT_CDCC
- dcc_sendfrom_queue();
- #endif
- }
- }
-
- static void dcc_rename (char *command, char *args)
- {
- DCC_list *Client;
- char *user;
- char *description;
- char *newdesc;
- char *temp;
-
- if (!(user = next_arg(args, &args)) || !(temp = next_arg(args, &args)))
- {
- put_it("%s", convert_output_format("$G %RDCC%n You must specify a nick and a new filename", NULL, NULL));
- return;
- }
- if ((newdesc = next_arg(args, &args)) != NULL)
- description = temp;
- else
- {
- newdesc = temp;
- description = NULL;
- }
-
- if ((Client = dcc_searchlist(description, user, DCC_FILEREAD, 0, NULL, NULL, 0)))
- {
- /* Is this needed now? */
- if (!(Client->flags & DCC_OFFER))
- {
- put_it("%s", convert_output_format("$G %RDCC Too late to rename that file", NULL, NULL));
- return;
- }
- malloc_strcpy(&(Client->description), newdesc);
- put_it("%s", convert_output_format("$G %RDCC File $0 from $1 rename to $2", "%s %s %s", description?description:"(null)", user, newdesc));
- }
- else
- put_it("%s", convert_output_format("$G %RDCC No file $0 from $1 found, or it's too late to rename", "%s %s", description?description:"(null)", user));
- }
-
- /*
- * close_all_dcc: We call this when we create a new process so that
- * we don't leave any fd's lying around, that won't close when we
- * want them to..
- */
- extern void close_all_dcc _((void))
- {
- DCC_list *Client, *last;
-
- for (Client = ClientList; Client; Client = last)
- {
- last = Client->next;
- dcc_erase(Client);
- }
- dcc_active_count = 0;
- }
-
-
- /* Looks for the dcc transfer that is "current" (last recieved data)
- * and returns information for it
- */
- extern char *DCC_get_current_transfer _((void))
- {
- return DCC_current_transfer_buffer;
- }
-
- BUILT_IN_COMMAND(chat)
- {
- int no_chat = 0;
- if (!my_strnicmp(command, "NOC", 3))
- no_chat = 1;
- if (args && *args)
- {
- char *tmp = NULL;
- if (no_chat)
- malloc_sprintf(&tmp, "CLOSE CHAT %s", args);
- else
- malloc_sprintf(&tmp, "CHAT %s", args);
- process_dcc(tmp);
- new_free(&tmp);
- }
- else if (last_chat_req)
- {
- DCC_list *chat_req = NULL;
- if ((chat_req = dcc_searchlist("chat", last_chat_req, DCC_CHAT, 0, NULL, NULL, no_chat?-1:0)))
- {
- if (no_chat)
- {
- dcc_close_filename(NULL, last_chat_req, "CHAT", DCC_CHAT);
- new_free(&last_chat_req);
- }
- else
- {
- char nick[BIG_BUFFER_SIZE];
- dcc_open(chat_req);
- sprintf(nick, "=%s", chat_req->user);
- addtabkey(nick, "msg", 0);
- }
- }
- else
- bitchsay("Error occurred");
- } else
- userage(command, helparg);
- }
-
-
- static void DCC_close_filesend (DCC_list *Client, char *type)
- {
- char lame_ultrix[30]; /* should be plenty */
- char lame_ultrix2[30];
- char lame_ultrix3[30];
- char buffer[200];
- char *tofrom = NULL;
- time_t xtime;
- double xfer;
-
- xtime = time_diff(Client->starttime, get_time(NULL));
- xfer = (double)(Client->bytes_sent ? Client->bytes_sent : Client->bytes_read);
-
- if (xfer <= 0)
- xfer = 1;
- if (xtime <= 0)
- xtime = 1;
- sprintf(lame_ultrix, "%2.4g", (xfer/ 1024.0 / xtime));
- /* Cant pass %g to put_it (lame ultrix/dgux), fix suggested by sheik. */
- sprintf(lame_ultrix2, "%2.4g%s", _GMKv(xfer), _GMKs(xfer));
- sprintf(lame_ultrix3, "%2.4g", (double)xtime);
- sprintf(buffer, "%%s %s %%s %%s TRANSFER COMPLETE", type);
-
- switch(get_to_from(dcc_types[Client->flags&DCC_TYPES]))
- {
- case 0:
- case 1:
- tofrom = "to";
- break;
- case 2:
- case 3:
- tofrom = "from";
- break;
- default:
- tofrom = "to";
- break;
- }
- if(do_hook(DCC_LOST_LIST,buffer,Client->user, check_paths(Client->description), lame_ultrix))
- put_it("%s", convert_output_format(fget_string_var(FORMAT_DCC_LOST_FSET),
- "%s %s %s %s %s %s %s %s %s", update_clock(GET_TIME), type,
- check_paths(Client->description), lame_ultrix2, tofrom, Client->user,
- lame_ultrix3, lame_ultrix, "Kb"));
-
- dcc_update_stats(Client);
- if (get_to_from(dcc_types[Client->flags&DCC_TYPES]) != -1 && dcc_active_count)
- dcc_active_count--;
-
- if (Client->read != Client->write)
- close (Client->write);
- FD_CLR(Client->write, &writables);
-
- new_close(Client->read);
- new_close(Client->file);
-
- Client->file = Client->read = Client->write = -1;
- Client->flags |= DCC_DELETE;
- *DCC_current_transfer_buffer = 0;
- update_transfer_buffer("");
- update_all_status(current_window, NULL, 0);
- }
-
- char transfer_buffer[BIG_BUFFER_SIZE];
-
- static void update_transfer_buffer (char *format, ...)
- {
- register DCC_list *Client = ClientList;
- unsigned count= 0;
- double perc = 0.0;
- char temp_str[60];
-
- errno = 0;
- *transfer_buffer = 0;
- for (Client = ClientList ; Client; Client = Client->next)
- {
- double bytes;
- unsigned long flags = Client->flags & DCC_TYPES;
-
- if ((flags == DCC_RAW) || (flags == DCC_RAW_LISTEN) || (flags == DCC_CHAT) || (flags == DCC_BOTMODE) || (flags == DCC_FTPOPEN))
- continue;
- if ((Client->flags & DCC_WAIT) || (Client->flags == DCC_DELETE))
- continue;
- bytes = Client->bytes_read + Client->bytes_sent + Client->transfer_orders.byteoffset;
- if (bytes >= 0)
- {
- if (Client->filesize >= bytes && (Client->filesize > 0))
- {
- perc = (100.0 * ((double)bytes) / (double)(Client->filesize));
- if ( perc > 100.0) perc = 100.0;
- else if (perc < 0.0) perc = 0.0;
-
- }
- sprintf(temp_str,"%d%%,",(int) perc);
- strcat(transfer_buffer,temp_str);
- }
- if (count++ > 9)
- break;
- }
- if (count)
- {
- chop(transfer_buffer, 1);
- if (fget_string_var(FORMAT_DCC_FSET))
- {
- sprintf(DCC_current_transfer_buffer, convert_output_format(fget_string_var(FORMAT_DCC_FSET), "%s", transfer_buffer));
- chop(DCC_current_transfer_buffer, 4);
- }
- else
- sprintf(DCC_current_transfer_buffer, "[%s]", transfer_buffer);
- }
- else
- *DCC_current_transfer_buffer = 0;
- }
-
- int get_to_from(char *Type) {
- if (!my_stricmp(Type, "SEND"))
- return 0;
- else if (!my_stricmp(Type, "RESEND"))
- return 1;
- else if (!my_stricmp(Type, "GET"))
- return 2;
- else if (!my_stricmp(Type, "REGET"))
- return 3;
- else if (!my_stricmp(Type, "TSEND"))
- return 4;
- else if (!my_stricmp(Type, "TRESEND"))
- return 5;
- else if (!my_stricmp(Type, "TGET"))
- return 6;
- else if (!my_stricmp(Type, "TREGET"))
- return 7;
- else
- return -1;
- }
-
- static void dcc_help1 (char *command, char *args)
- {
- char *comm;
- int i, c;
- char buffer[BIG_BUFFER_SIZE+1];
- if (args && *args)
- {
- comm = next_arg(args, &args);
- upper(comm);
- for (i = 0; dcc_commands[i].name != NULL; i++)
- {
- if (!strncmp(comm, dcc_commands[i].name, strlen(comm)))
- {
- put_it("%s", convert_output_format("$G Usage: %W/%R$0%n $1 %K-%n $2-", "DCC %s %s", dcc_commands[i].name, dcc_commands[i].help?dcc_commands[i].help:"No help availble yet"));
- return;
- }
- }
- }
- put_it("%s", convert_output_format("$G %RDCC%n help -", NULL, NULL));
- *buffer = 0;
- c = 0;
- for (i = 0; dcc_commands[i].name; i++)
- {
- strcat(buffer, dcc_commands[i].name);
- strcat(buffer, space);
- if (++c == 5)
- {
- put_it("%s", convert_output_format("$G $[13]0 $[13]1 $[13]2 $[13]3 $[13]4", "%s", buffer));
- *buffer = 0;
- c = 0;
- }
- }
- if (c)
- put_it("%s", convert_output_format("$G $[13]0 $[13]1 $[13]2 $[13]3 $[13]4", "%s", buffer));
- userage("dcc help", "[command] to get help on specific commands");
- }
-
- static void dcc_show_active(char *command, char * args)
- {
- put_it("%s", convert_output_format("$G %RDCC%n DCC Active = \002$0\002, Limit = \002$1\002",
- "%d %d", dcc_active_count, get_int_var(DCC_SEND_LIMIT_VAR)));
- }
-
- static void dcc_set_quiet(char *command, char *args )
- {
- dcc_quiet ^=1;
- put_it("%s", convert_output_format("$G %RDCC%n DCC Quiet = \002$0\002", "%s", on_off(dcc_quiet)));
- }
-
- /* returns the string without the path (if present) */
- static char * strip_path(char *str)
- {
- char *ptr;
-
- ptr = strrchr(str,'/');
- if (ptr == NULL)
- return str;
- else
- return ptr+1;
- }
-
- /* returns the string without the path (if present) */
- static char *check_paths(char *str)
- {
- if (dcc_paths == 0)
- return strip_path(str);
- else
- return str;
- }
-
- static void dcc_set_paths(char *command, char *args)
- {
- dcc_paths ^= 1;
-
- put_it("%s", convert_output_format("$G %RDCC%n DCC paths is now \002$0\002", "%s", on_off(dcc_paths)));
- }
-
- static void dcc_tog_rename(char *command, char *args)
- {
- int arename = get_int_var(DCC_AUTORENAME_VAR);
- arename ^= 1;
- set_int_var(DCC_AUTORENAME_VAR, arename);
- put_it("%s", convert_output_format("$G %RDCC%n DCC auto rename is now \002$0\002", "%s", on_off(get_int_var(DCC_AUTORENAME_VAR))));
- }
-
- static void dcc_overwrite_toggle(char *command, char *args)
- {
- dcc_overwrite_var ^= 1;
-
- put_it("%s", convert_output_format(" DCC overwrite is now \002$0\002", "%s", on_off(dcc_overwrite_var)));
- }
-
- void dcc_tog_auto(char *command, char *args)
- {
- int dcc_auto = get_int_var(DCC_AUTOGET_VAR);
- dcc_auto ^= 1;
- set_int_var(DCC_AUTOGET_VAR, dcc_auto);
- put_it("%s", convert_output_format(" DCC autoget is now \002$0\002", "%s", on_off(dcc_auto)));
- }
-
- void dcc_stats (char *command, char *unused)
- {
- char max_rate_in[20];
- char min_rate_in[20];
- char max_rate_out[20];
- char min_rate_out[20];
-
- sprintf(max_rate_in, "%6.2f", dcc_max_rate_in/1024.0);
- sprintf(min_rate_in, "%6.2f", ((dcc_min_rate_in != DBL_MAX )?dcc_min_rate_in/1024.0: 0.0));
- sprintf(max_rate_out, "%6.2f", dcc_max_rate_out/1024.0);
- sprintf(min_rate_out, "%6.2f", ((dcc_min_rate_out != DBL_MAX) ? dcc_min_rate_out/1024.0: 0.0));
- if (do_hook(DCC_TRANSFER_STAT_LIST, "%lu %s %s %lu %s %s %lu %u %u %s %s %s %s",
- (unsigned long)dcc_bytes_in, max_rate_in, min_rate_in,
- (unsigned long)dcc_bytes_out, max_rate_out, min_rate_out,
- (unsigned long)(send_count_stat+get_count_stat),
- dcc_active_count, get_int_var(DCC_SEND_LIMIT_VAR),
- on_off(get_int_var(DCC_AUTOGET_VAR)), on_off(dcc_paths),
- on_off(dcc_quiet), on_off(dcc_overwrite_var)))
- {
- char in[50], out[50];
- sprintf(in, "%3.2f%s", _GMKv(dcc_bytes_in), _GMKs(dcc_bytes_in));
- sprintf(out, "%3.2f%s", _GMKv(dcc_bytes_out), _GMKs(dcc_bytes_out));
-
- #ifdef ONLY_STD_CHARS
- put_it("%s",convert_output_format(" %G========================%K[%Cdcc transfer stats%K]%G=======================", NULL));
- put_it("%s",convert_output_format(" %G| |", NULL));
- put_it("%s",convert_output_format(" %G|%g|-%K[%Cx%cferd %Ci%cn%K]%g-|-%K[%Cx%cferd %Co%cut%K]%g-|-%K[%Ct%cotal %Cf%ciles%K]%g-|-%K[%Ca%cctive%K]%g-|-[%Cl%cimit%K]%g-|%G|", NULL));
- put_it("%s",convert_output_format(" %G|%g| %W$[-10]0 %g| %W$[-10]1 %g| %W$[-10]2 %g| %W$[-8]3 %g| %W$[-7]4 %g|%G|", "%s %s %d %d %d", in, out,send_count_stat+get_count_stat,dcc_active_count,get_int_var(DCC_SEND_LIMIT_VAR)));
- put_it("%s",convert_output_format(" %G|%g|------------|-------------|---------------|----------|---------|%G|", NULL));
- put_it("%s",convert_output_format(" %G| |", NULL));
- put_it("%s",convert_output_format(" %g|----%K[%Ci%cn %Cs%ctats%K]%g---|---%K[%Co%cut %Cs%ctats%K]%g---|----------%K[%Ct%coggles%K]%g----------|", NULL));
- put_it("%s",convert_output_format(" %g| %Cm%nax: %W$[-6]0%n%Rkb/s %g| %Cm%nax: %W$[-6]1%n%Rkb/s %g| %Ca%nutoget: %W$[-3]2%n %Cp%naths: %W$[-3]3 %g|", "%s %s %s %s", max_rate_in, max_rate_out, on_off(get_int_var(DCC_AUTOGET_VAR)),on_off(dcc_pat
-
-
- hs)));
- put_it("%s",convert_output_format(" %g| %Cm%nin: %W$[-6]0%n%Rkb/s %g| %Cm%nin: %W$[-6]1%n%Rkb/s %g| %Co%nverwrite: %W$[-3]2%n %Cq%nuiet: %W$[-3]3 %g|", "%s %s %s %s", min_rate_in, min_rate_out, on_off(dcc_overwrite_var), on_off(dcc_quiet)));
- put_it("%s",convert_output_format(" %g|-----------------|-----------------|-----------------------------|", NULL));
-
- #else
-
- put_it("%s",convert_output_format(" %G╒═══════════════════════%K[%Cdcc transfer stats%K]%G══════════════════════╕", NULL));
- put_it("%s",convert_output_format(" %G│ │", NULL));
- put_it("%s",convert_output_format(" %G│%g╓─%K[%Cx%cferd %Ci%cn%K]%g─╓-%K[%Cx%cferd %Co%cut%K]%g─╖─%K[%Ct%cotal %Cf%ciles%K]%g─╓─%K[%Ca%cctive%K]%g─╖─[%Cl%cimit%K]%g─╖%G│", NULL));
- put_it("%s",convert_output_format(" %G│%g║ %W$[-10]0 %g║ %W$[-10]1 %g║ %W$[-10]2 %g║ %W$[-8]3 %g║ %W$[-7]4 %g║%G│", "%s %s %d %d %d", in, out,send_count_stat+get_count_stat,dcc_active_count,get_int_var(DCC_SEND_LIMIT_VAR)));
- put_it("%s",convert_output_format(" %G│%g╙────────────╜─────────────╙───────────────╜──────────╙─────────╜%G│", NULL));
- put_it("%s",convert_output_format(" %G│ │", NULL));
- put_it("%s",convert_output_format(" %g╓────%K[%Ci%cn %Cs%ctats%K]%g───╓───%K[%Co%cut %Cs%ctats%K]%g───╖──────────%K[%Ct%coggles%K]%g──────────╖", NULL));
- put_it("%s",convert_output_format(" %g║ %Cm%nax: %W$[-6]0%n%Rkb/s %g║ %Cm%nax: %W$[-6]1%n%Rkb/s %g║ %Ca%nutoget: %W$[-3]2%n %Cp%naths: %W$[-3]3 %g║", "%s %s %s %s", max_rate_in, max_rate_out, on_off(get_int_var(DCC_AUTOGET_VAR)),on_off(dcc_pat
- hs)));
- put_it("%s",convert_output_format(" %g║ %Cm%nin: %W$[-6]0%n%Rkb/s %g║ %Cm%nin: %W$[-6]1%n%Rkb/s %g║ %Co%nverwrite: %W$[-3]2%n %Cq%nuiet: %W$[-3]3 %g║", "%s %s %s %s", min_rate_in, min_rate_out, on_off(dcc_overwrite_var), on_off(dcc_quiet)));
- put_it("%s",convert_output_format(" %g╙─────────────────╜─────────────────╙─────────────────────────────╜", NULL));
-
- #endif
-
- }
- }
-
- /*
- * only call this on dcc finish
- */
- static void dcc_update_stats (DCC_list *Client)
- {
- time_t xtime = time_diff(Client->starttime, get_time(NULL));
-
- dcc_bytes_in += Client->bytes_read;
- dcc_bytes_out += Client->bytes_sent;
- if (xtime <= 0)
- xtime = 1;
- if (Client->bytes_read)
- {
- get_count_stat++;
- if ((double)Client->bytes_read/(double)xtime > dcc_max_rate_in)
- dcc_max_rate_in = (double)Client->bytes_read/(double)xtime;
- if ((double)Client->bytes_read/ (double)xtime < dcc_min_rate_in)
- dcc_min_rate_in = (double)Client->bytes_read/(double)xtime;
- }
- if (Client->bytes_sent)
- {
- send_count_stat++;
- if ((double)Client->bytes_sent/(double)xtime > dcc_max_rate_out)
- dcc_max_rate_out = (double)Client->bytes_sent/(double)xtime;
- if ((double)Client->bytes_sent/(double)xtime < dcc_min_rate_out)
- dcc_min_rate_out = (double)Client->bytes_sent/ (double)xtime;
- }
- }
-
- unsigned char byteordertest(void)
- {
- unsigned short test = DCC_PACKETID;
-
- if (*((unsigned char *)&test) == ((DCC_PACKETID & 0xff00) >> 8))
- return 0;
-
- if (*((unsigned char *)&test) == (DCC_PACKETID & 0x00ff))
- return 1;
- return 0;
- }
-
- /*
- * This stuff doesnt conform to the protocol.
- * Thanks mirc for disregarding the protocol.
- */
- #ifdef MIRC_BROKEN_DCC_RESUME
- extern int doing_msg, doing_notice;
-
- /*
- * Usage: /DCC RESUME <nick> [file] [-e passkey]
- */
- void dcc_getfile_resume (char *command, char *args)
- {
- char *user, *nick;
- char *filename = NULL;
- char *fullname = NULL;
- char *tmp = NULL;
- DCC_list *Client;
- char *passwd = NULL;
- struct stat sb;
- char buf[10];
-
- #ifdef PUBLIC_ACCESS
- bitchsay("This command has been disabled on a public access system");
- return;
- #endif
- if (!(user = next_arg(args, &args)))
- {
- say("You must supply a nickname for DCC RESUME");
- return;
- }
-
- if (args && *args)
- {
- /* Leeme lone, Yoshi. :P */
- if (args[0] != '-' || args[1] != 'e')
- filename = next_arg(args, &args);
-
- if (args && args[0] == '-' && args[1] == 'e')
- {
- next_arg(args, &args);
- passwd = next_arg(args, &args);
- }
- }
-
-
- while ((nick = next_in_comma_list(user, &user)))
- {
- if (!nick || !*nick)
- break;
- if (!(Client = dcc_searchlist(filename, nick, DCC_FILEREAD, 0, NULL, NULL, 0)))
- {
- if (filename)
- say("No file (%s) offered in SEND mode by %s", filename, nick);
- else
- say("No file offered in SEND mode by %s", nick);
- return;
- }
-
- if (get_string_var(DCC_DLDIR_VAR))
- malloc_sprintf(&tmp, "%s/%s", get_string_var(DCC_DLDIR_VAR), Client->description);
- else
- tmp = m_strdup(Client->description);
-
- if (!(fullname = expand_twiddle(tmp)))
- malloc_strcpy(&fullname, tmp);
- /*
- * This has to be done by hand, we cant use send_ctcp,
- * because this violates the protocol, and send_ctcp checks
- * for that. Ugh.
- */
-
- if (stat(fullname, &sb) == -1)
- {
- /* File doesnt exist. Sheesh. */
- say("DCC RESUME: Cannot use DCC RESUME if the file doesnt exist. [%s|%s]", fullname, strerror(errno));
- return;
- }
-
- if ((Client->flags & DCC_ACTIVE) || (Client->flags & DCC_WAIT))
- {
- say("A previous DCC GET:%s to %s exists", filename?filename:"<any>", nick);
- return;
- }
-
- if (passwd)
- Client->encrypt = m_strdup(passwd);
- Client->bytes_sent = 0L;
- Client->transfer_orders.byteoffset = sb.st_size;
-
- sprintf(buf, "%hd", ntohs(Client->remport));
- malloc_strcpy(&Client->othername, buf);
-
- malloc_strcpy(&Client->othername, ltoa((long)ntohs(Client->remport)));
-
- /* Just in case we have to fool the protocol enforcement. */
- doing_privmsg = doing_notice = in_ctcp_flag = 0;
- send_ctcp(CTCP_PRIVMSG, nick, CTCP_DCC, "RESUME %s %d %d", Client->description, ntohs(Client->remport), (unsigned int)sb.st_size);
- }
-
- new_free(&tmp);
- new_free(&fullname);
- /* Then we just sit back and wait for the reply. */
- }
-
- /*
- * When the peer demands DCC RESUME
- * We send out a DCC ACCEPT
- */
- static void dcc_getfile_resume_demanded (char *user, char *filename, char *port, char *offset)
- {
- DCC_list *Client;
-
- if (!(Client = dcc_searchlist(filename, user, DCC_FILEOFFER, 0, port, NULL, 0)))
- return; /* Its a fake. */
-
- if (!offset)
- return; /* Its a fake */
-
- Client->transfer_orders.byteoffset = my_atol(offset);
- Client->bytes_read = 0L;
-
- doing_privmsg = doing_notice = in_ctcp_flag = 0;
- send_ctcp(CTCP_PRIVMSG, user, CTCP_DCC, "ACCEPT %s %s %s", filename, port, offset);
-
- /* Wait for them to open the connection */
- }
-
-
- /*
- * When we get the DCC ACCEPT
- * We start the connection
- */
- static void dcc_getfile_resume_start (char *nick, char *filename, char *port, char *offset)
- {
- DCC_list *Client;
- char *fullname = NULL;
- char *tmp = NULL;
-
- #ifdef PUBLIC_ACCESS
- bitchsay("This command has been disabled on a public access system");
- return;
- #endif
- if (!(Client = dcc_searchlist(filename, nick, DCC_FILEREAD, 0, port, NULL, 0)))
- return; /* Its fake. */
-
- Client->flags |= DCC_TWOCLIENTS;
- if (!dcc_open(Client))
- return;
-
- if (get_string_var(DCC_DLDIR_VAR))
- malloc_sprintf(&tmp, "%s/%s", get_string_var(DCC_DLDIR_VAR), Client->description);
- else
- tmp = m_strdup(Client->description);
- if (0 == (fullname = expand_twiddle(tmp)))
- malloc_strcpy(&fullname, tmp);
-
- #if defined(WINNT) || defined(__EMX__)
- if (!(Client->file = open(fullname, O_WRONLY | O_APPEND | O_BINARY/*, 0644*/)))
- #else
- if (!(Client->file = open(fullname, O_WRONLY | O_APPEND, 0644)))
- #endif
- {
- put_it("%s", convert_output_format("$G %RDCC%n Unable to open $0: $1-", "%s %s", Client->description, errno?strerror(errno):"Unknown"));
- Client->flags |= DCC_DELETE;
- }
-
- new_free(&fullname);
- new_free(&tmp);
- }
-
- #endif
-
-
-
-
- void dcc_check_idle _((void))
- {
- register DCC_list *Client = NULL, *tmpClient;
-
- time_t dcc_idle_time = get_int_var(_CDCC_CLOSE_IDLE_SENDS_TIME_VAR);
- static char *last_notify = NULL;
- int minidlecheck = get_int_var(_CDCC_MINSPEED_TIME_VAR);
-
- if (dcc_idle_time)
- {
- int this_idle_time = dcc_idle_time;
- int erase_it;
- for (Client = ClientList; Client;)
- {
- time_t client_idle = time(NULL) - Client->lasttime.tv_sec;
- if (client_idle <= 0 ) client_idle = 1;
- erase_it = 0;
- tmpClient = Client->next;
- switch (Client->flags & DCC_TYPES)
- {
- case DCC_FILEOFFER:
- case DCC_FILEREAD:
- case DCC_RESENDOFFER:
- case DCC_REGETFILE:
- this_idle_time = dcc_idle_time * 3;
- break;
- default:
- this_idle_time = dcc_idle_time;
- break;
- }
- if ((client_idle > this_idle_time) && !(Client->flags&DCC_ACTIVE))
- {
- put_it("%s", convert_output_format("$G %RDCC%n Auto-closing idle dcc $0 to $1", "%s %s", dcc_types[Client->flags&DCC_TYPES], Client->user));
- if (!last_notify || strcmp(Client->user,last_notify))
- {
- send_to_server("NOTICE %s :Dcc %s Auto Closed", Client->user, dcc_types[Client->flags&DCC_TYPES]);
- malloc_strcpy(&last_notify, Client->user);
- }
- if ((get_to_from(dcc_types[Client->flags & DCC_TYPES]) != -1))
- if (dcc_active_count)
- dcc_active_count--;
- erase_it = 1;
- }
- #ifdef WANT_CDCC
- if (Client->flags&DCC_ACTIVE)
- {
- switch (Client->flags & DCC_TYPES)
- {
- case DCC_FILEOFFER:
- case DCC_RESENDOFFER:
- if (cdcc_minspeed && minidlecheck && ((client_idle % minidlecheck) == 0))
- {
- unsigned long sent = Client->bytes_sent / 1024;
- double this_speed = 0.0;
- char lame_ultrix1[20];
- char lame_ultrix[20];
- this_speed = (double)((double) sent / (double)client_idle);
-
- if (this_speed < cdcc_minspeed)
- {
- sprintf(lame_ultrix, "%2.4g", (double)(sent / client_idle));
- sprintf(lame_ultrix1,"%2.4g", (double)cdcc_minspeed);
- put_it("%s", convert_output_format("$G %RDCC%n Auto-closing Slow dcc $0 to $1 require $2KB/s got $3KB/s", "%s %s %s %s", dcc_types[Client->flags&DCC_TYPES], Client->user, lame_ultrix1, lame_ultrix));
- if (!last_notify || strcmp(Client->user,last_notify))
- {
- send_to_server("NOTICE %s :CDCC Slow dcc %s Auto Closed. Require %sKB/s got %sKB/s", Client->user, dcc_types[Client->flags&DCC_TYPES], lame_ultrix1, lame_ultrix);
- malloc_strcpy(&last_notify, Client->user);
- }
- if (dcc_active_count)
- dcc_active_count--;
- erase_it = 1;
- }
- }
- default:
- break;
- }
- }
- #endif
- if (erase_it)
- dcc_erase(Client);
- Client = tmpClient;
- }
- }
- #ifdef WANT_CDCC
- cdcc_timer_offer();
- #endif
- }
-
- BUILT_IN_COMMAND(dcx)
- {
- char *user = NULL;
- int do_chat = 0;
- int do_send = 0;
- int do_get = 0;
- int do_all = 0;
- char *nick;
- context;
- do_chat = !my_stricmp(command, "dcx");
- do_send = !my_stricmp(command, "dcs");
- do_get = !my_stricmp(command, "dcg");
- do_all = !my_stricmp(command, "dca");
-
- if (!do_all && !(user = next_arg(args, &args)))
- {
- userage(command, helparg);
- return;
- }
-
- if (do_all && !user)
- {
- dcc_close_all();
- dcc_active_count = 0;
- update_all_status(current_window, NULL, 0);
- return;
- }
- while ((nick = next_in_comma_list(user, &user)))
- {
- if (!nick || !*nick)
- break;
- if (do_send)
- {
- dcc_close_type_nick_all("SEND", nick);
- dcc_close_type_nick_all("RESEND", nick);
- }
- else if (do_get)
- {
- dcc_close_type_nick_all("GET", nick);
- dcc_close_type_nick_all("REGET", nick);
- }
- else if (do_chat)
- dcc_close_type_nick_all("CHAT", nick);
- }
- update_all_status(current_window, NULL, 0);
- return;
- }
-
- #ifdef WANT_FTP
- void open_ftpsend (DCC_list *client, char *args)
- {
- struct sockaddr_in data_addr = { 0 };
- int len = sizeof(struct sockaddr_in);
- char tmp[2048];
- int on = 1, data = -1, s1 = -1;
- char *a, *p;
- DCC_list *Client = NULL;
- char *bufptr;
- if (client->in_ftp)
- {
- put_it("%s", convert_output_format("$G %gFTP%n already transfering a file.", NULL, NULL));
- return;
- }
- if (getsockname(client->read, (struct sockaddr *)&data_addr, &len) < 0)
- return;
-
- data_addr.sin_port = 0;
- if ((data = socket(AF_INET, SOCK_STREAM, 0)) < 0)
- return;
- if ((setsockopt(data, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on))) < 0)
- return;
- if ((bind(data, (struct sockaddr *)&data_addr, sizeof(data_addr))) < 0)
- return;
- len = sizeof(struct sockaddr_in);
- getsockname(data, (struct sockaddr *)&data_addr, &len);
-
- if ((listen(data, 4)) < 0)
- return;
-
- a = (char *)&data_addr.sin_addr;
- p = (char *)&data_addr.sin_port;
- #define UC(b) (((int)b)&0xff)
- dcc_printf(client->read, "PORT %d,%d,%d,%d,%d,%d\n", UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]),UC(p[0]), UC(p[1]));
- #undef UC
- dcc_printf(client->read, "stor %s\n", args);
-
- memset(tmp, 0, sizeof(tmp));
- bufptr = tmp;
- while (1)
- {
- if (dgets(bufptr, client->read, 1) == -1 && dgets_errno > 0)
- goto error_ftpsend;
- if (*bufptr == '5')
- goto error_ftpsend;
- else if (strstr(tmp, "BINARY mode data connection"))
- break;
- }
- len = sizeof(struct sockaddr_in);
- if ((s1 = accept(data, (struct sockaddr *) &data_addr, &len)) < 0)
- return;
- close(data);
-
- if ((Client = dcc_searchlist("ftpsend", args, DCC_FTPSEND, 1, client->user, NULL, -1)))
- {
- struct stat st;
- Client->read = Client->write = s1;
- #if defined(WINNT) || defined(__EMX__)
- Client->file = open(args, O_RDONLY | O_BINARY);
- #else
- Client->file = open(args, O_RDONLY);
- #endif
- fstat(Client->file, &st);
- Client->flags |= DCC_ACTIVE;
- new_open(Client->read);
- Client->filesize = st.st_size;
- get_time(&Client->starttime);
- client->in_ftp = 1;
- }
- return;
- error_ftpsend:
- close(data);
- chop(tmp, 2);
- put_it("%s", convert_output_format("$G %gFTP%n $0-", "%s", tmp));
- return;
- }
-
- void open_ftpget(DCC_list *client, char *args)
- {
- struct sockaddr_in data_addr = { 0 };
- int len = sizeof(struct sockaddr_in);
- char tmp[2048];
- int on = 1, data = -1, s1 = -1;
- char *a, *p, *bufptr;
- DCC_list *Client = NULL;
- off_t filesize = 0;
- char *filename = NULL;
-
- if (client->in_ftp)
- {
- put_it("%s", convert_output_format("$G %gFTP%n already transfering a file.", NULL, NULL));
- return;
- }
- if (getsockname(client->read, (struct sockaddr *)&data_addr, &len) < 0)
- return;
-
- data_addr.sin_port = 0;
- if ((data = socket(AF_INET, SOCK_STREAM, 0)) < 0)
- return;
- if ((setsockopt(data, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on))) < 0)
- return;
- if ((bind(data, (struct sockaddr *)&data_addr, sizeof(data_addr))) < 0)
- return;
- len = sizeof(struct sockaddr_in);
- getsockname(data, (struct sockaddr *)&data_addr, &len);
-
- if ((listen(data, 4)) < 0)
- return;
-
- a = (char *)&data_addr.sin_addr;
- p = (char *)&data_addr.sin_port;
- #define UC(b) (((int)b)&0xff)
- dcc_printf(client->read, "PORT %d,%d,%d,%d,%d,%d\n", UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]),UC(p[0]), UC(p[1]));
- #undef UC
-
- dcc_printf(client->read, "retr %s\n", args);
-
- memset(tmp, 0, sizeof(tmp));
- bufptr = tmp;
- while (1)
- {
- if (dgets(bufptr, client->read, 1) == -1 && dgets_errno > 0)
- goto error_ftp;
- if (*bufptr == '5')
- goto error_ftp;
- else if (strstr(tmp, "BINARY mode data connection"))
- {
- int i = 0;
- char *q = tmp;
- for (i = 0; i < 9; i++)
- p = next_arg(q, &q);
- if (p)
- {
- p++;
- filesize = my_atol(p);
- }
- break;
- }
- }
-
- len = sizeof(struct sockaddr_in);
- if ((s1 = accept(data, (struct sockaddr *) &data_addr, &len)) < 0)
- return;
- close(data);
-
- #if defined(WINNT) || defined(__EMX__)
- if ((p = strrchr(args, '/')) || (p = strrchr(args, '\\')))
- #else
- if ((p = strrchr(args, '/')))
- #endif
- filename = ++p;
- else
- filename = args;
-
- if ((Client = dcc_searchlist("ftpget", filename, DCC_FTPGET, 1, client->user, NULL, -1)))
- {
- Client->read = Client->write = s1;
- #if defined(WINNT) || defined(__EMX__)
- Client->file = open(filename, O_WRONLY|O_CREAT|O_TRUNC | O_BINARY/*, 0644*/);
- #else
- Client->file = open(filename, O_WRONLY|O_CREAT|O_TRUNC, 0644);
- #endif
- Client->flags |= DCC_ACTIVE;
- new_open(Client->read);
- Client->filesize = filesize;
- get_time(&Client->starttime);
- if (do_hook(FTP_LIST, "%s %s", "FTP Attempting to get", filename))
- put_it("%s", convert_output_format("$G %gFTP%n Attempting to get $0", "%s", filename));
- client->in_ftp = 1;
- }
- return;
- error_ftp:
- close(data);
- chop(tmp, 2);
- put_it("%s", convert_output_format("$G %gFTP%n $0-", "%s", tmp));
- return;
- }
-
- int dcc_ftpcommand _((char *host, char *args))
- {
- DCC_list *Client;
- Client = dcc_searchlist("ftpopen", host, DCC_FTPOPEN, 0, NULL, NULL, -1);
- if (Client && !Client->in_ftp)
- {
- char *command = next_arg(args, &args);
- char *t_host;
- if (!my_strnicmp(command, "ls",2) || !my_strnicmp(command, "dir",3))
- dcc_printf(Client->read, "stat %s\n", (args && *args) ? args : ".");
- else if (!my_strnicmp(command, "more", 3))
- dcc_printf(Client->read, "stat %s\n", (args && *args) ? "cwd" : "pwd", (args && *args) ?args:empty_string);
- else if (!my_strnicmp(command, "cd", 2))
- dcc_printf(Client->read, "%s%s%s\n", (args && *args) ? "cwd" : "pwd", (args && *args) ? " ":empty_string, (args && *args) ?args:empty_string);
- else if (!my_strnicmp(command, "get",3) && args && *args)
- open_ftpget(Client, args);
- else if (!my_strnicmp(command, "put",3) && args && *args)
- open_ftpsend(Client, args);
- else
- dcc_printf(Client->read, "%s%s%s\n", command, (args && *args) ? " ":empty_string, (args && *args) ? args:empty_string);
- t_host = alloca(strlen(host)+4);
- strcpy(t_host, "-"); strcat(t_host, host);
- addtabkey(t_host, "msg", 0);
- }
- else if (Client && Client->in_ftp)
- {
- if (do_hook(FTP_LIST, "%s", "FTP transfering a file"))
- put_it("%s", convert_output_format("$G %gFTP%n transfering a file.", NULL, NULL));
- return 0;
- }
- else
- {
- if (do_hook(FTP_LIST, "%s", "FTP is not connected"))
- put_it("%s", convert_output_format("$G %gFTP%n is not connected.", NULL, NULL));
- return 0;
- }
- return 1;
- }
-
- void dcc_ftpopen(char *command, char *args )
- {
- DCC_list *Client;
- char user[] = "anonymous";
- char pass[] = "- bxuser@";
- char *host, *u = user, *p = pass;
- char *t_host;
- int port = 21;
-
- if (!(host = next_arg(args, &args)))
- {
- put_it ("%s /dcc ftp hostname user passwd [-p port]", convert_output_format("$G %RDCC%n", NULL, NULL));
- return;
- }
- u = user;
- p = pass;
- while (args && *args)
- {
- if (args && *args && *args == '-' && *(args+1) == 'p')
- {
- char *t;
- t = next_arg(args, &args);
- t = next_arg(args, &args);
- if (t)
- port = my_atol(t);
- break;
- }
- if (!(u = next_arg(args, &args)))
- u = user;
- if (!(p = next_arg(args, &args)))
- p = pass;
- }
-
- Client = dcc_searchlist("ftpopen", host, DCC_FTPOPEN, 1, NULL, NULL, -1);
- if (!Client) return;
-
- if ((Client->flags & DCC_ACTIVE) || (Client->flags & DCC_WAIT))
- {
- put_it("%s", convert_output_format("$G %GFTP%n A previous DCC FTP to $0 exists", "%s", host));
- return;
- }
- Client->remport = port;
- malloc_strcpy(&Client->encrypt, p);
- malloc_strcpy(&Client->user, host);
- malloc_strcpy(&Client->othername, u);
-
- #if defined(WINNT) || defined(__EMX__)
- if ((Client->read = connect_by_number(host, &Client->remport, SERVICE_CLIENT, PROTOCOL_TCP, 0)) < 0)
- #else
- if ((Client->read = connect_by_number(host, &Client->remport, SERVICE_CLIENT, PROTOCOL_TCP, 1)) < 0)
- #endif
- {
- Client->flags |= DCC_DELETE;
- put_it("%s", convert_output_format("$G %gFTP%n command failed connect", NULL, NULL));
- return;
- }
- Client->remport = ntohs(Client->remport);
- #ifdef DCC_CNCT_PEND
- Client->flags |= DCC_WAIT|DCC_CNCT_PEND;
- #else
- Client->flags |= DCC_WAIT;
- #endif
-
- new_open(Client->read);
- t_host = alloca(strlen(host)+4);
- strcpy(t_host, "-"); strcat(t_host, host);
- addtabkey(t_host, "msg", 0);
- }
-
- static void dcc_ftpget (char *command, char *args)
- {
- char *host; char *file = NULL;
- DCC_list *Client;
- if (!(host = next_arg(args, &args)))
- {
- return;
- }
- if (args && *args)
- file = next_arg(args, &args);
-
- Client = dcc_searchlist(file, host, DCC_XMITRECV, 1, NULL, NULL, -1);
- if (Client)
- {
- Client->flags &=DCC_WAIT;
- new_open(Client->read);
- }
-
- }
-
- #ifdef FTP_XMIT
- static void dcc_xmitget (char *user, char *description, char *address, char *port)
- {
- DCC_list *Client;
- unsigned long TempLong;
- unsigned int TempInt;
- unsigned short TempSh;
-
- #ifdef PUBLIC_ACCESS
- bitchsay("This command has been disabled on a public access system");
- #endif
- Client = dcc_searchlist(description, user, DCC_XMITRECV, 1, NULL, NULL, -1);
-
- if (Client->flags & DCC_ACTIVE)
- {
- put_it("%s", convert_output_format("$G %RDCC%n Recieved DCC $0 request from $1 while previous session active", "%s %s", "XMIT", user));
- message_from(NULL, LOG_CRAP);
- return;
- }
- Client->flags |= DCC_OFFER;
-
- TempLong = strtoul(address, NULL, 10);
- Client->remote.s_addr = htonl(TempLong);
- TempSh = TempInt = (unsigned) strtoul(port, NULL, 10);
- Client->remport = htons(TempInt);
- #if defined(WINNT) || defined(__EMX__)
- if ((Client->read = connect_by_number(address, &TempSh, SERVICE_SERVER, PROTOCOL_TCP, 0)) < 0)
- #else
- if ((Client->read = connect_by_number(address, &TempSh, SERVICE_SERVER, PROTOCOL_TCP, 1)) < 0)
- #endif
- {
- Client->flags |= DCC_DELETE;
- return;
- }
- /* FD_SET(Client->read, &readables);*/
- new_open(Client->read);
- }
- #endif
-
- static void dcc_ftpsend (char *command, char *args)
- {
-
- char *user = NULL;
- char *filename = NULL, *p;
- struct in_addr myip;
- char *tmp = NULL;
- DCC_list *Client = NULL;
- unsigned short portnum;
- char *fullname = NULL;
- struct stat st;
-
- #ifdef PUBLIC_ACCESS
- bitchsay("This command has been disabled on a public access system");
- #endif
- if (!(user = next_arg(args, &args)) || !(filename = next_arg(args, &args)))
- {
- say("You must supply a nickname and a filename for DCC XMIT");
- return;
- }
-
- #ifndef WINNT
- if (scanstr("/etc/", filename))
- {
- put_it("%s", convert_output_format("$G %RDCC%n Send request for /etc rejected", NULL, NULL));
- return;
- }
- #endif
- fullname = expand_twiddle(filename);
- Client = dcc_searchlist(filename, user, DCC_XMITSEND, 1, fullname, NULL, -1);
- if ((Client->flags & DCC_ACTIVE) || (Client->flags & DCC_WAIT))
- {
- put_it("%s", convert_output_format("$G %RDCC%n A previous DCC send:$0 to $1 exists", "%s %s", filename, user));
- return;
- }
-
- #if defined(WINNT) || defined(__EMX__)
- if ((Client->read = connect_by_number(NULL, &portnum, SERVICE_SERVER, PROTOCOL_TCP, 0)) < 0)
- #else
- if ((Client->read = connect_by_number(NULL, &portnum, SERVICE_SERVER, PROTOCOL_TCP, 1)) < 0)
- #endif
- {
- put_it("%s", convert_output_format("$G %RDCC%n Unable to create connection: $0-", "%s", errno ? strerror(errno) : "Unknown Host"));
- message_from(NULL, LOG_CRAP);
- dcc_erase(Client);
- return;
- }
- Client->remport = htons(portnum);
- new_open(Client->read);
- myip.s_addr = server_list[from_server].local_addr.s_addr;
-
-
- if (myip.s_addr == htonl(0x7f000001))
- myip.s_addr = MyHostAddr.s_addr;
-
- #if defined(WINNT) || defined(__EMX__)
- if ((p = strrchr(filename, '/')) || (p = strrchr(filename, '\\')))
- #else
- if ((p = strrchr(filename, '/')))
- #endif
- malloc_strcpy(&tmp, ++p);
- else
- tmp = m_strdup(filename);
- stat(fullname, &st);
- Client->filesize = st.st_size;
- send_ctcp(CTCP_PRIVMSG, user, CTCP_XMIT, "clear %lu %d %s",
- (unsigned long)htonl(myip.s_addr), Client->remport, tmp);
- #ifdef DCC_CNCT_PEND
- Client->flags |= DCC_WAIT|DCC_CNCT_PEND;
- #else
- Client->flags |= DCC_WAIT;
- #endif
- new_free(&tmp);
- }
-
- static void process_incoming_ftp (register DCC_list *client)
- {
- char tmp[MAX_DCC_BLOCK_SIZE * 4 + 1];
- unsigned int bytesread = 0;
- char *bufptr;
- if ((client->flags & DCC_TYPES) == DCC_FTPGET)
- {
- DCC_list *new = NULL;
- if ((bytesread = read(client->write, &tmp, sizeof(tmp)-1)) > 0)
- {
- client->bytes_read +=bytesread;
- client->packets_transfer++;
- if ((write(client->file, tmp, bytesread)) != bytesread)
- {
- client->flags |= DCC_DELETE;
- client->read = -1;
- if ((new = dcc_searchlist("ftpopen", client->othername, DCC_FTPOPEN, 0, NULL, NULL, 1)))
- new->in_ftp = 0;
- }
- }
- else
- {
- if ((new = dcc_searchlist("ftpopen", client->othername, DCC_FTPOPEN, 0, NULL, NULL, 1)))
- new->in_ftp = 0;
- DCC_close_filesend(client, "FTPGET");
- }
- return;
- }
- if (client->flags & DCC_WAIT)
- {
- if ((dcc_printf(client->read, "user %s\n", client->othername) < 0) || (dcc_printf(client->read, "pass %s\n", client->encrypt) < 0))
- {
- client->flags |= DCC_DELETE;
- put_it("%s", convert_output_format("$G %gFTP%n command failed write", NULL, NULL));
- return;
- }
- dcc_printf(client->read, "type i\n");
- new_free(&client->encrypt);
-
- client->flags |= DCC_ACTIVE;
- client->flags &= ~DCC_WAIT;
- return;
- }
- bufptr = tmp;
- bytesread = dgets(bufptr, client->read, 1);
- switch (bytesread)
- {
- case -1:
- {
- client->flags |= DCC_DELETE;
- break;
- }
- case 0:
- break;
- default:
- {
- char *num;
- char *p, *t;
- chop(tmp, 2);
- t = p = m_strdup(tmp);
- num = next_arg(p, &p);
- message_from(client->user, LOG_DCC);
- if (do_hook(FTP_LIST, "%s %s", num, p))
- {
- if (num && isdigit(*num))
- put_it("%s", convert_output_format("$G %gFTP%n $0-", "%s", p));
- else
- put_it("%s", convert_output_format(tmp, NULL, NULL));
- }
- new_free(&t);
- }
- }
- message_from(NULL, LOG_CRAP);
- }
-
- static void process_outgoing_ftp (DCC_list *client)
- {
- char tmp[MAX_DCC_BLOCK_SIZE * 4 + 1];
- unsigned int bytesread = 0;
- DCC_list *new = NULL;
- if ((bytesread = read(client->file, &tmp, sizeof(tmp)-1)) > 0)
- {
- client->bytes_sent +=bytesread;
- client->packets_transfer++;
- if ((send(client->write, tmp, bytesread, 0)) != bytesread)
- {
- client->flags |= DCC_DELETE;
- if ((new = dcc_searchlist("ftpopen", client->othername, DCC_FTPOPEN, 0, NULL, NULL, 1)))
- new->in_ftp = 0;
- }
- }
- else
- {
- if ((new = dcc_searchlist("ftpopen", client->othername, DCC_FTPOPEN, 0, NULL, NULL, 1)))
- new->in_ftp = 0;
- DCC_close_filesend(client, "FTPSEND");
- }
- return;
- }
- #endif
-
- int check_dcc_list (char *name)
- {
- register DCC_list *Client;
- int do_it = 0;
- for (Client = ClientList; Client; Client = Client->next)
- {
- if (Client->user && !my_stricmp(name, Client->user) && !(Client->flags & DCC_ACTIVE))
- {
- Client->flags |= DCC_DELETE;
- do_it++;
- if (get_to_from(dcc_types[Client->flags&DCC_TYPES]) != -1 && dcc_active_count)
- dcc_active_count--;
- }
- }
- return do_it;
- }
-
- void dcc_nick (char *command, char *args)
- {
- int remove;
- List *nptr = NULL;
- char *nick;
- if (!args || !*args)
- {
- int count = 0;
- for (nptr = next_namelist(dcc_no_flood, NULL, DCC_HASHSIZE); nptr; nptr = next_namelist(dcc_no_flood, nptr, DCC_HASHSIZE))
- {
- if (count == 0)
- put_it("%s", convert_output_format("$G %RDCC%n autoget list/no flood list", NULL, NULL));
- put_it("%s", nptr->name);
- count++;
- }
- if (count == 0)
- userage("/dcc exempt", "+nick to add, nick to remove");
- return;
- }
- nick = next_arg(args, &args);
- while (nick && *nick)
- {
- remove = 1;
- if (*nick == '+')
- {
- remove = 0;
- nick++;
- }
- nptr = find_name_in_genericlist(nick, dcc_no_flood, DCC_HASHSIZE, remove);
- if (remove && nptr)
- {
- new_free(&nptr->name);
- new_free((char **)&nptr);
- }
- else if (!remove && !nptr)
- add_name_to_genericlist(nick, dcc_no_flood, DCC_HASHSIZE);
- else if (remove && !nptr)
- put_it("%s", convert_output_format("$G: %RDCC%n No such nick on the exempt list %K[%W$0%K]", "%s", nick));
- nick = next_arg(args, &args);
- }
- }
-
- int dcc_exempt_save(FILE *fptr)
- {
- int count = 0;
- List *nptr = NULL;
- if (dcc_no_flood)
- {
- fprintf(fptr, "# Dcc Exempt from autoget OFF list\n");
- fprintf(fptr, "DCC EXEMPT ");
- }
- for (nptr = next_namelist(dcc_no_flood, NULL, DCC_HASHSIZE); nptr; nptr = next_namelist(dcc_no_flood, nptr, DCC_HASHSIZE))
- {
- fprintf(fptr, "+%s ", nptr->name);
- count++;
- }
- if (dcc_no_flood)
- {
- fprintf(fptr, "\n");
- if (count && do_hook(SAVEFILE_LIST, "DCCexempt %d", count))
- bitchsay("Saved %d DccExempt entries", count);
-
- }
- return count;
- }
-